Spring 2.5 Annotation

Spring 2.5 Annotation

Reference:
    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

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

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

Spring with 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">

    <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>

注入属性 @Autowired
//标注在字段上
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

@Resource 注入属性
    @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;
}

JSR 250
    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 销毁方法的执行
    }

使用<context:annotation-config/> 简化配置
    <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>

使用 @Component
    通过 @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 {
            …
        }

采用具有特殊语义的注释
    @Repository, @Service, @Controller, @Component 是等效的
    但是从注释类的命名上,这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。
    虽然目前这 3 个注释和 @Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。
    所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository, @Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释。

猜你喜欢

转载自louisling.iteye.com/blog/1981600
今日推荐