`
gao_xianglong
  • 浏览: 466978 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

剖析Spring3.x的“自动性”

 
阅读更多

《剖析Spring3.x的“自动性”》

 

前言

其实这篇博文,只是有感而发,或者说是对之前博客(

详解SSJ(Spring3.x mvc + Spring3.x Core + JPA2.x)轻量级集成开发目录汇总

)不全面或者遗漏的一种补充。算了,不扯那么远了,直接进入正题。

 

目录

一、基于注解的自动装配;

二、自动装配时如果被装配的对象构造带参数怎么办?

三、为什么更多人会使用@Resource取代@Autowired?

四、自动扫描组件;

五、自动扫描组件中的过滤器;

 

一、基于注解的自动装配

其实笔者之前在SSJ的系列博文的中,已经对组件装配进行过详细且深入的讲解,但是笔者发现,还是有很多开发人员对注解一知半解。因此咱们从头再来学习一遍。从Spring2.5开始,已经开始支持自动装配了,其中基于注解的自动装配是未来的趋势。

 

简单来说,要想让Spring支持基于注解的自动装配,那么要做的事情,只有几点,首先第一件事情就是在Spring配置文件中声明"<context:annotation-config/>"标签,该标签的作用,就是用于支持基于注解的自动装配,当然使用这个标签的时候,千万不要忘记了导入context的命令空间,否则该标签将不可用。当在Spring的配置文件中声明好context命名空间和"<context:annotation-config/>"标签后,基本上事情就成功一大半了,接下来要做的事情就是在需要被注入代码位置添加@Autowired注解进行标注即可。如下所示:

定义需要被装配的bean组件:

public class UserBean {
	@Value("JohnGao")
	private String userName;

	@Value("123456")
	private String passWord;
        /* 此处省略set和get方法 */
}

 

不知道大家是否用过@Value注解,一般来说,对于字面值的定义,我们没有必要在Spring2.5以后还在配置文件中定义,然后使用@Autowired注解的方式进行装配,直接使用@Value注解即可。或许有人脑袋瓜子转得快,既然是硬编码定义字面值,我为么不直接定义,还需要多绕几个圈子跑到@Value注解上去定义,这岂不是脱了裤子放屁,多此一举?其实使用@Value真正的目的是配合SpEL(Spring3.x后提供)表达式语言,这才会体现出使用@Value注解的强大和灵活。这里笔者仅仅举个例子:@Value("#{userBean2.userName}"),这句话的意思,就是引用userBean2中userName字段的字面值,关于SpEL表达式,笔者在后续章节中会开贴专门进行讲解,前提是我得有时间。

 

spring配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
			http://www.springframework.org/schema/context 
			http://www.springframework.org/schema/context/spring-context-3.1.xsd">
	<!-- 自动装配注解 -->
	<context:annotation-config />
	<bean id="userBean" class="com.johngao.test.UserBean" />
</beans>

 

使用基于注解的自动装配后,配置文件中几乎没有什么内容了,大家明显可以发现原本需要投值注入的标签<property>或者构造注入的<constructor-arg>标签都统统消失了。通过注解的方式对配置代码进行了“瘦身”,这对于不喜欢,甚至厌恶XML配置的人,完全可以算得上是一种福音

 

测试用例:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:*-context.xml")
public class UseTest {
	@Autowired
	private UserBean userBean;
	@Test
	public void testA() {
		if (null != userBean) {
			System.out.println(userBean.getUserName() + "\n"
					+ userBean.getPassWord());
		}
	}
}

 

上述程序示例非常简单,使用@Autowired注解进行自动装配。有一点笔者得提出来,@Autowired注解缺省是强制要求被标注的目标是必须能够被装配的,否则将会抛出令人讨厌的org.springframework.beans.factory.NoSuchBeanDefinitionException异常。当然如果你是在不想看到这个异常,@Autowired注解提供了一项参数“required”,缺省情况该参数是为“true”,如果我们将其设置为“false”的时候,一旦Spring发现被标注的目标无法被装配时,也不会再抛出NoSuchBeanDefinitionException异常。

 

二、自动装配时如果被装配的对象构造带参数怎么办?

习惯性使用基于注解进行自动装配的开发人员,应该发现了一个问题,就像笔者之前演示的例子一样,被装配的目标对象都是无参构造,但是如果带参呢?那么如果是构造函数带参,有2个方式可以解决,一种是放弃使用基于注解的自动装配而采用传统的基于配置文件形式,而另外一种则还是使用@Autowired。

 

就像笔者之前所说,很多开发人员对注解的一知半解导致很多情况下觉得基于注解的方式是有局限性的,当然笔者承认局限性是有,但是一定不是你所想象的那样。接下来笔者将会对@Autowired注解进行细致的讲解,如果你不懂,麻烦你看仔细了。首先第一步,我们首先打开源码,看看@Autowired注解的可用作用域,如下所示:

@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

	/**
	 * Declares whether the annotated dependency is required.
	 * <p>Defaults to <code>true</code>.
	 */
	boolean required() default true;
}

 

从源码可以明显看出, @Autowired注解的作用域是比较广的,不仅可以作用域字段、方法上,还可以作用在构造函数上。那么这就意味着,如果需要被装配的目标对象构造带参数,这不要紧,只需要在其构造函数上方标注@Autowired注解即可解决。

 

三、为什么更多人会使用@Resource取代@Autowired?

这个问题,其实笔者之前在系列博文也讲过,如果你没有映像了,没关系,现在也可以在笔者的带领下进行回顾。我们都知道Spring最早诞生的时候,所承诺的就是低侵入性,没错Spring确实也做到了,基本上在Spring2.5的时候,业务逻辑中几乎没有Spring的代码,但是2.5以后,随着注解的逐渐流行,第三方的注解确实已经不知不觉嵌入在我们的代码中了,尽管这并不是太大的问题(反向依赖),但仍然具备侵入性。如果想完全做到无侵入性,那么只能够使用JSR规范提供的组件注解,这样一来,哪怕某一天我不用Spring,而使用其他厂商提供的IOC组件时,我也不用更改嵌套在我业务逻辑中的注解代码,明白了吗,各位亲?

 

JSR提供了几种注解,比如笔者最常用的@Resource和最讨厌的@Inject,前者是JSR-250提供的,而后者则是JSR-330,如果你不懂什么是JSP和JCP,麻烦自行google补脑,废话不多说。这里我简单先说一下,@Autowired和@Inject是基于类型的装配,一旦代码中有多个类型相同的类型时,Spring就会抛出异常,通常这种情况下我们可以使用@Autowired和@Qualifier进行注解联用,这样一来@Autowired就变成名称装配,不会再因为定义的类型相同而触发异常(IOC容器规定Bean名称必须唯一)。

 

@Resource由J2EE(JSR-250)规范提供,目的很简单就是取缔@Autowired。J2EE推荐使用@Resource是因为其更加优秀。@Resource不仅支持类型装配,还支持名称装配。@Resource缺省按照名称装配,只有在找不到指定的bean时才按照类型进行装配。

 

四、自动扫描组件;

自动装配爽吗?你肯定已经感受到它的便捷了,那么除了自动装配外,Spring在2.5之后还提供了自动扫描组件。其实所谓的自动扫描,指的就是<bean>标签你也完全不需要在Spring配置文件中进行定义了,这样一来,配置文件中的内容,几乎“清理”干净了。Spring提供了如下4个注解,用于声明哪些需要被自动扫描的组件,如下所示:

1、@Component:用于声明不好归类的组件;

2、@Controller:用于声明Action组件;
3、@Service:用于声明Service组件;
4、@Repository:用于声明Dao组件;

 

当然要想让Spring支持自动扫描组件,还需要在配置文件中定义一项标签“<context:component-scan base-package="com.*.*.test"/>”,该标签的作用就是用于支持自动组件扫描。这里有一点笔者必须提醒大家,是否还记得之前我们定义的用于支持自动装配的“<context:annotation-config />”标签?干掉他,是的,你没有听错,因为“<context:component-scan>”标签具有和它完全一样的功能,并且还支持自动组件扫描,那么有了“<context:component-scan>”之后,顺理成章“<context:annotation-config />”标签也就是多余的了。

 

五、自动扫描组件中的过滤器;

“<context:component-scan>”标签中还包含有2个子标签,分别是“<context:exclude-filter>”和“<context:include-filter>”标签,其实这2个标签的作用就是对自动扫描组件的一种补充,使得“<context:component-scan>”标签更加灵活。或许你会问我,什么场景下需要使用到这2个子标签?试想一下,如果某些情况下,我们希望所使用的第三方组件(只有字节码),也能够让Spring支持自动扫描组件时,由于无法在别人的源码上添加@Component注解,因此按常理来说,我们是没有办法办到的,但是“<context:include-filter>”过滤器将会让这个“梦想”具备可能性。如下所示:

<context:component-scan base-package="com.*.*.test">
		<context:include-filter type="assignable" expression="com.johngao.test.TestA"/>
</context:component-scan>

 

上述代码示例中,笔者的TestA类是没有使用@Component注解的,但是一旦我配置有“<context:exclude-filter>”标签后,TestA类以及其所有派生类都不需要再加上@Component注解进行标注,都可以被Spring执行自动组件扫描,以便于被实现自动装配。当然使用“<context:exclude-filter>”需要注意的是,该过滤器的过滤目标是依赖“<context:component-scan>”标签的“ base-package”属性的。相反“<context:exclude-filter>”过滤器指的就是哪些组件不需要被自动扫描并注册为Spring Bean。

 

关于过滤器的属性“type”,则有5种类型,分别为assignable、annotation、aspectj、custom,以及regex,关于各个类型的区别,请自定google补脑。

分享到:
评论

相关推荐

    精通Spring4.x(包含源码)

    5. **Spring Boot**:虽然不是Spring4.x的核心部分,但作为Spring生态的一部分,Spring Boot简化了Spring应用的初始设置和运行,通过自动配置和起步依赖,使得快速构建微服务成为可能。 6. **Hibernate与MyBatis**...

    spring4.x源码

    Spring框架是Java开发中不可或缺的一部分,它以其模块化、易用性和灵活性著称。Spring4.x版本是该框架的一个重要里程碑,引入了许多新特性和改进。在这个源码包中,我们可以深入探究Spring的核心机制,理解它如何...

    Spring 3.x 企业应用开发实战-源代码

    《Spring 3.x 企业应用开发实战》是一本深度探讨Spring框架在企业级应用中的实践指南,特别适合那些想要深入理解和应用Spring 3.x版本的开发者。这本书通过丰富的实例和详细的代码,帮助读者掌握如何利用Spring进行...

    精通spring4.x企业应用开发实战 源代码

    这个压缩包中的源代码正是基于Spring 4.x的企业级应用示例,通过分析这些代码,我们可以深入理解Spring的核心概念和实际应用。 1. **依赖注入(Dependency Injection, DI)** Spring的核心特性之一就是依赖注入,它...

    精通Spring 4.x企业应用开发实战_源码

    5. **Spring Boot**:虽然不在4.x版本中,但Spring Boot在4.x基础上发展起来,它极大地简化了Spring应用的初始设置和配置,提供了自动配置和起步依赖,使得快速开发成为可能。 6. **Spring Security**:Spring的...

    Spring3.x MVC 例子

    Spring3.x MVC是Java开发中广泛使用的一个框架,它提供了模型-视图-控制器(MVC)架构,用于构建高效、可维护的Web应用程序。在本教程中,我们将深入探讨Spring3.x MVC的关键特性,通用配置,以及在企业级项目中的...

    spring5.x 整合 mybatis 3.x

    通过以上步骤,我们可以将 Spring 5.x 和 MyBatis 3.x 完美整合,并利用 Druid 数据连接池提升应用的性能和稳定性。在实际开发中,根据具体需求,可以进一步优化配置,例如使用 Spring Boot 自动配置、事务管理等,...

    org.springframework.core_3.1.1.RELEASE.jar

    7. `org.springframework.core.type`: 提供了类型扫描和类型分析的工具,是Spring自动配置和组件扫描的基础。 三、3.1.1.RELEASE版本的改进 在`3.1.1.RELEASE`版本中,Spring对核心模块进行了一些优化: 1. 更强的...

    精通Spring2.x-企业应用开发详解

    《精通Spring2.x-企业应用开发详解》是一本深度解析Spring框架2.x版本的...通过分析这些源代码,读者不仅可以深入了解Spring2.x的核心机制,还能学习到如何在实际项目中应用这些技术,提升企业级应用的开发效率和质量。

    Spring.3.x企业应用开发实战(完整版).part2

    16.7.3 使用Spring RestTemplate测试 16.7.4 使用Selenium测试 16.8 小结 第17章 实战案例开发 17.1 论坛案例概述 17.1.1 论坛整体功能结构 17.1.2 论坛用例描述 17.1.3 主要功能流程描述 17.2 系统设计 17.2.1 技术...

    Spring3.x企业应用开发实战源代码

    《Spring3.x企业应用开发实战》是一本深受开发者欢迎的技术书籍,其提供的源代码涵盖了Spring框架在企业级应用中的各种实际应用场景。通过分析这些源代码,我们可以深入理解Spring框架的核心特性和最佳实践。 首先...

    Spring+3.x企业应用开发实战光盘maven整合代码

    《Spring+3.x企业应用开发实战光盘maven整合代码》是针对Spring 3.x版本在企业级项目中应用的实战教程,其中包含了如何利用Maven进行项目构建和管理依赖的过程。在这个压缩包中,主要文件名为"spring3.x",意味着它...

    Spring3.x企业应用开发实战(完整版) part1

    16.7.3 使用Spring RestTemplate测试 16.7.4 使用Selenium测试 16.8 小结 第17章 实战案例开发 17.1 论坛案例概述 17.1.1 论坛整体功能结构 17.1.2 论坛用例描述 17.1.3 主要功能流程描述 17.2 系统设计 17.2.1 技术...

    spring-framework-5.1.x.zip

    《深入剖析Spring Framework 5.1.x:源码解析与实战指南》 Spring Framework作为Java领域最广泛应用的轻量级框架之一,其5.1.x版本的发布带来了许多改进和新特性,为开发者提供了更高效、更灵活的开发体验。本篇...

    springblade.zip

    3. **安全性**:集成Apache Shiro或Spring Security进行权限控制,确保系统的安全性和稳定性。 4. **缓存管理**:支持Redis作为缓存管理工具,提高数据读取速度,减轻数据库压力。 5. **数据持久层**:使用MyBatis...

    spring-boot-2.4.x.zip

    在2.4.x版本中,Spring Boot引入了更多优化和新特性,进一步提升了开发效率和应用程序的稳定性。 一、Spring Boot 2.4.x核心概念 1. 自动配置:Spring Boot的核心在于自动配置,它通过扫描`@...

    Java架构师之源码分析专题SpringBoot2.x、Spring5、SpringMVC、Mybatis源码分析

    通过对这些核心组件的了解,可以提高你的Spring应用性能和可维护性。 SpringMVC作为Spring框架的一部分,负责处理HTTP请求和响应。源码解析将揭示DispatcherServlet的工作流程,包括控制器的查找,模型视图的构建,...

    Spring+3.x企业应用开发实战+源码.rar

    《Spring 3.x企业应用开发实战》是一本深入讲解如何使用Spring框架进行企业级应用程序开发的书籍,结合了源码分析,旨在帮助开发者熟练掌握Spring的核心技术和实际运用。该书适用于有一定Java基础并希望深入了解...

    springStudy:精通spring4.x企业应用开发实战

    《Spring4.x企业应用开发实战》是一本深入探讨Spring框架在企业级开发中的应用书籍,主要针对Spring 4.x版本进行讲解。Spring是Java领域中最受欢迎的轻量级框架之一,它提供了丰富的功能来简化应用程序的开发,包括...

Global site tag (gtag.js) - Google Analytics