Spring 2.5 Annotation

[b]Spring 2.5 Annotation[/b]

[b]Reference:[/b]
http://www.ibm.com/developerworks/cn/java/j-lo-spring25-ioc/
http://www.ibm.com/developerworks/cn/java/j-lo-spring25-mvc/
http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-iocannt/
http://www.ibm.com/developerworks/cn/java/
《精通 Spring 2.x—企业应用开发精解》陈雄华 ([email protected]), 技术总监, 宝宝淘网络科技有限公司
http://download.csdn.net/detail/zheng12tian/2584987

[b]Appicable scene:[/b]
Spring with Annotation:
1) Bean 的依赖关系是固定的,(如 Service 使用了哪几个 DAO 类),这种配置信息不会在部署时发生调整。
2) 类是自己写的,可以在源码里面加入 Annotation.

Spring with XML:
1) 部署时需要修改的,放在xml里面修改后不需要编译源码,例如: 数据源、缓存池、持久层操作模板类、事务管理等内容的配置。
2) 引用第三方库,则无法修改源代码,例如:JdbcTemplate、SessionFactoryBean

[b]Spring with xml:[/b]
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="boss" class="com.baobaotao.Boss">
<property name="car" ref="car"/>
<property name="office" ref="office" />
</bean>

<bean id="office" class="com.baobaotao.Office">
<property name="officeNo" value="002"/>
</bean>

<bean id="car" class="com.baobaotao.Car" scope="singleton">
<property name="brand" value="Jaguar XJ"/>
<property name="price" value="89"/>
</bean>
</beans>

[b]注入属性 @Autowired[/b]
//标注在字段上
public class Boss {
@Autowired
private Car car;

@Autowired
private Office office;
}

//标注在方法上
public class Boss {
private Car car;
private Office office;

@Autowired
public void setCar(Car car) {
this.car = car;
}
}

//标注在构造函数上
public class Boss {
private Car car;
private Office office;

@Autowired
public Boss(Car car ,Office office){
this.car = car;
this.office = office ;
}
}
//beans.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<!-- Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。-->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

<!-- 移除 boss Bean 的属性注入配置的信息, 扫描 Autowired 标注,注入属性, 默认按类型匹配 -->
<bean id="boss" class="com.baobaotao.Boss"/>

<bean id="office" class="com.baobaotao.Office">
<property name="officeNo" value="001"/>
</bean>

<bean id="car" class="com.baobaotao.Car" scope="singleton">
<property name="brand" value="Bugatti"/>
<property name="price" value="4200"/>
</bean>
</beans>

1) 当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。可以使用 @Autowired(required = false)
2) 如果 Spring 容器中拥有多个候选 Bean,Spring 容器在启动时也会抛出 BeanCreationException 异常。
public class Boss {
@Autowired
private Car car;

@Autowired
@Qualifier("office")
private Office office;
}

@Autowired
public void setOffice(@Qualifier("office") Office office) {
this.office = office;
}

@Autowired 可以对成员变量、方法以及构造函数
@Qualifier 的标注对象是成员变量、方法入参、构造函数入参。
//自动注入的策略就从 byType 转变成 byName

[b]@Resource 注入属性[/b]
@Autowired 是 Spring 提供的, 默认按 byType 自动注入
@Resource 是 JSR250 定义的, Spring 也支持,与 @Autowired 等效, (默认按 byName 自动注入)

让 @Resource 生效,需要加 <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>

public class Boss {
// 自动注入类型为 Car 的 Bean
@Resource
private Car car;

// 自动注入 bean 名称为 office 的 Bean
@Resource(name = "office")
private Office office;
}

[b]JSR 250[/b]
JSR250 定义了 @Resource, @PostConstruct 和 @PreDestroy
@PostConstruct / @PreDestroy 等效于 实现 InitializingBean/DisposableBean 接口进行初始化和销毁。也可以通过 <bean> 元素的 init-method/destroy-method 属性指定初始化之后 / 销毁之前调用的操作方法。
@PostConstruct 可以定义在多个初始化方法上。而接口或者 init-method 只能一个。

让 JSR250的 Annotations 生效, 需要在 xml 里面加 BeanPostProcessor:
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>

public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] {"beans.xml"};);
Boss boss = (Boss) ctx.getBean("boss");
System.out.println(boss);
ctx.destroy();// 关闭 Spring 容器,以触发 Bean 销毁方法的执行
}

[b]使用<context:annotation-config/> 简化配置[/b]
<context:annotationconfig/> 将隐式地向 Spring 容器注册 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor。

//beans.xml
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<context:annotation-config/>

<bean id="boss" class="com.baobaotao.Boss"/>

<bean id="office" class="com.baobaotao.Office">
<property name="officeNo" value="001"/>
</bean>

<bean id="car" class="com.baobaotao.Car" scope="singleton">
<property name="brand" value=" 红旗 CA72"/>
<property name="price" value="2000"/>
</bean>
</beans>

[b]使用 @Component[/b]
通过 @Autowired 或 @Resource 在 Bean 类中使用自动注入功能,
但是 Bean 还是在 XML 文件中通过 <bean> 进行定义 —— 也就是说,在 XML 配置文件中定义 Bean,通过 @Autowired 或 @Resource 为 Bean 的成员变量、方法入参或构造函数入参提供自动注入的功能。
通过注释定义 Bean,从 XML 配置文件中完全移除 Bean 定义的配置: @Component

//默认实例化为 car,首字母小写,也可以指定名称。 @Component("myCar")
@Component
public class Car {

}

@Component("boss")
public class Boss {
@Autowired
private Car car;

@Autowired
private Office office;

}

//beans.xml
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<context:component-scan base-package="com.baobaotao"/>
</beans>

Filter:
<context:component-scan base-package="com.baobaotao">
<context:include-filter type="regex" expression="com\.baobaotao\.service\..*"/>
<context:exclude-filter type="aspectj" expression="com.baobaotao.util..*"/>
</context:component-scan>

<context:component-scan/>
不但启用了对类包进行扫描以实施注释驱动 Bean 定义的功能,
同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor),
因此当使用 <context:component-scan/> 后,就可以将 <context:annotation-config/> 移除了。

Scope
默认情况下通过 @Component 定义的 Bean 都是 singleton 的,如果需要使用其它作用范围的 Bean,可以通过 @Scope 注释来达到目标

@Scope("prototype")
@Component("boss")
public class Boss {

}

[b]采用具有特殊语义的注释[/b]
@Repository, @Service, @Controller, @Component 是等效的
但是从注释类的命名上,这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。
虽然目前这 3 个注释和 @Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。
所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository, @Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章