`
ahjdzx1990
  • 浏览: 24989 次
  • 性别: Icon_minigender_1
  • 来自: 安徽
社区版块
存档分类
最新评论

基于Annotation方式的Bean装配

 
阅读更多

6.2.6  基于Annotation方式的Bean装配

从JDK 5开始提供名为Annotation(注释)的功能,它被定义为JSR-175规范。在Java应用中,我们经常会遇到一些需要使用模板代码的情况。例如,为了编写一个JAX-RPC Web Service,我们必须提供一对接口和实现作为模板代码。如果使用Annotation对远程访问的方法代码进行修饰的话,这个模板就能够使用工具自动生成。另外,一些API需要使用与程序代码同时维护的附属文件。例如,JavaBeans需要一个BeanInfo Class与一个Bean同时使用/维护,而EJB则同样需要一个部署描述符,此时在程序中使用Annotation来维护这些附属文件的信息将十分便利而且减少了错误。

注释是以"@注释名"或"@注释名(参数名=参数值)"的形式在代码中存在的。例如,JDK 5内置的基本注释@Override 、@Deprecated 、@SuppressWarnings(value="unchecked")。注释可以附加在package、 class、method、 field等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问。如果没有外部解析工具等对其加以解析和处理的情况,本身不会对Java的源代码或class文件等产生任何影响,也不会对它们的执行产生任何影响。

在Spring中尽管使用XML配置文件可以完成所有的配置工作,直观表达Java EE程序员的"装配意图",但如果应用中Bean数量成千上万的话,最终会导致XML配置文件体积剧增,面对臃肿的XML配置文件,给维护与升级带来一定的困难。

那有没有一种行之有效的XML配置文件减肥方案呢?伟大的Spring开发团队想到了JDK 1.5提供的新特性--Annotation注释技术。从Spring 2.0开始,逐步完善对Annotation注释技术的全面支持,使XML配置文件不再臃肿,向"零配置"目标靠拢。

对于初学者而言,也许觉得Annotation注释技术太神秘了,随便放个注释就有如此巨大的威力。在了解了Annotation注释的工作原理之后,方觉得真正伟大的不是Annotation注释本身,而是幕后默默无闻地进行注释处理的Annotation处理器。Annotation注释仅仅是一个标记,用以表达程序员的某种意图,如果不为之量身开发一个Annotation处理器的话,Annotation注释本身将毫无意义,对程序也不会产生任何影响。Annotation处理器是基于JDK的反射机制来实现的,Spring 2.5中定义的一系列Annotation注释,如表6-4所示,幕后均有相应的Annotation处理器与之对应,最终实现Annotation注释的特定语义。

表6-4  Spring 2.5中常用的Annotation注释说明

   

   

@Autowired

通过@Autowired注解对Bean的属性变量、属性的Setter方法及构造函数进行标注,配合对应的注解处理器AutowiredAnnotationBeanProcessor完成Bean的自动配置工作。@Autowired注解默认是按Bean类型进行装配的,也就是说注解处理器AutowiredAnnotationBeanProcessor会在Spring容器中寻找与@Autowired注解所在属性同类型的Bean实例进行装配,如果找到多个满足条件的Bean实例时,将会抛出NoSuchBeanDefinitionException异常。@Autowired注解加上@Qualifier注解的话,可以直接指定一个Bean实例名称来进行装配。在实例应用中,不推荐使用@Autowired注解,因为该注解应用不当,会引发一些莫名其妙的问题

@Resource

@Resource的作用相当于@Autowired,配合对应的注解处理器CommonAnnotationBeanPostProcessor完成Bean的自动配置工作。只不过@Autowired注解默认是按Bean类型进行装配的,而@Resource注解默认是按Bean实例名称进行装配罢了。@Resource有两个属性是比较重要的,分别是nametypeSpring@Resource注解的name属性解析为Bean实例的名字,而type属性则解析为Bean实例的类型。所以如果使用name属性,则按Bean实例名称进行装配,而使用type属性时则按Bean类型进行装配。如果既不指定name也不指定type属性,这时则先按Bean实例名称进行装配,如果匹配不到,再按Bean类型进行装配,如果都匹配不到,则抛出NoSuchBeanDefinitionException异常

@Qualifier

如果@Autowired注解加上@Qualifier注解的话,可以将默认按Bean类型进行装配变换为按Bean实例名称进行装配,具体的Bean实例名称由@Qualifier注解的参数指定

@PostConstruct

Bean中的某个方法上加上@PostConstruct注解,则该方法将会在Bean初始化之后被Spring容器调用,作用等同在Spring配置文件中为bean标签指定init-method属性

@PreDestroy

Bean中的某个方法上加上@PreDestroy注解,则该方法将会在Bean实例被销毁之前由Spring容器进行调用,作用等同在Spring配置文件中为bean标签指定destroy-method属性

在Java EE中启用Spring的注解装配通常需要经过以下几个步骤。

(1)导入Spring注解装配功能所依赖的JAR包Jcommon-annotations.jar,并将其加入到当前项目的classpath中来,该文件在spring-framework-2.5.6\spring-framework-2.5.6 \lib\j2ee文件夹下可以找到;

(2)在Spring配置文件中定义context命名空间与相应的schemaLocation:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans  
  3. xmlns="http://www.springframework.org/schema/beans" 
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  5. xmlns:context="http://www.springframework.org/schema/context" 
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans   
  7. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  8. http://www.springframework.org/schema/context  
  9. http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
  10. ……  
  11. </beans> 

(3)在Spring配置文件中开启相应的注解处理器:

  1. <!-- 开启注解处理器 -->  
  2. <context:annotation-config/> 

(4)在Bean中使用表6-4中列举的Annotation注释进行Bean属性的自动装配。

下面我们以一个简单的Java应用SpringAnnotationIOC具体演示一下基于Annotation注解方式的Bean装配。

首先定义一个用于演示原型模式下Bean实例化的User类,User类中的随机数生成器rnd是通过@Autowired注解加@Qualifier注解实现按Bean实例名称注入的,User实例的ID是在initUser()方法中赋予的随机整数,initUser()使用@PostConstruct注解被指定为初始化时调用的方法:

  1. package test.spring.bean;  
  2. import java.util.Random;  
  3. import javax.annotation.PostConstruct;  
  4. import org.springframework.beans.factory.annotation.Autowired;  
  5. import org.springframework.beans.factory.annotation.Qualifier;  
  6. /** 用户持久化类 */ 
  7. public class User {  
  8. Integer id;//自然ID号  
  9. String userName;  //用户名  
  10. String userPwd;//用户密码  
  11. //使用@Autowired注解加@Qualifier注解实现按Bean实例名称装配  
  12. @Autowired @Qualifier("random")  
  13. Random rnd;  
  14. //默认构造方法  
  15. public User(){}  
  16. //使用@PostConstruct注解指定初始化时调用的方法  
  17. @PostConstruct 
  18. public void initUser() {  
  19. this.id = rnd.nextInt(1000);//产生一个1000以内的随机ID  
  20. this.userName ="用户"+this.id;//产生一个相应的用户名  
  21. this.userPwd = "123456";//指定一个初始化密码  
  22. }  
  23. //省略属性的get/set方法对  

接下来定义一个用于演示@Resource、@Autowired、@PostConstruct、@PreDestroy等注解用法的业务类AnnotationIocBean:

  1. package test.spring.bean;  
  2. import java.text.SimpleDateFormat;  
  3. import java.util.*;  
  4. import javax.annotation.PostConstruct;  
  5. import javax.annotation.PreDestroy;  
  6. import javax.annotation.Resource;  
  7. import org.springframework.beans.factory.annotation.Autowired;  
  8. /** 用于演示XML方式装配Bean实例的测试类 */ 
  9. public class AnnotationIocBean {  
  10. //定义两个通过@Resource注解注入的属性,可省略set方法  
  11. @Resource Date now;  
  12. //为@Resource注解指定name属性,直接引用Bean工厂中的一个Bean实例  
  13. @Resource(name="simpleDateFormat")  
  14. SimpleDateFormat sf;  
  15. //定义User类型的属性,通过Annotation注解方式注入  
  16. User user1;  
  17. //定义两个通过@Autowired注解注入的属性,可省略set方法  
  18. @Autowired User user2;  
  19. @Autowired User user3;  
  20. //缺省构造方法  
  21. public AnnotationIocBean() {}  
  22. //使用@PostConstruct注解指定初始化时调用的方法  
  23. @PostConstruct 
  24. public void init() {  
  25. System.out.println("AnnotationIocBean被实例化了!");  
  26. }  
  27. //定义一个业务方法输出各属性值  
  28. public void execute(){  
  29. System.out.println("现在的时间是:"+sf.format(now));  
  30. System.out.println("第一个用户ID="+user1.getId());  
  31. System.out.println("第二个用户ID="+user2.getId());  
  32. System.out.println("第三个用户ID="+user3.getId());  
  33. }  
  34. //使用@PreDestroy注解指定实例销毁时调用的方法  
  35. @PreDestroy 
  36. public void destroy() {  
  37. System.out.println("AnnotationIocBean实例被销毁了!");  
  38. }  
  39. //通过在set方法上放置@Resource注解实现注解方式注入  
  40. @Resource 
  41. public void setUser1(User user) {  
  42. this.user1 = user;  
  43. }  

下面在Spring的XML配置文件中配置相关Bean的装配信息,与以前基于XML方式装配Bean相比,配置文件中节省了大量的property标记,从而使配置文件得以瘦身:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans  
  3. xmlns="http://www.springframework.org/schema/beans" 
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  5. xmlns:context="http://www.springframework.org/schema/context" 
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans   
  7. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  8. http://www.springframework.org/schema/context  
  9. http://www.springframework.org/schema/context/spring-context-2.5.xsd">      
  10. <!-- 开启注解处理器 -->  
  11. <context:annotation-config/>      
  12. <!-- 通过构造方法注入属性值装配SimpleDateFormat单实例 -->  
  13. <bean id="simpleDateFormat" class="java.text.SimpleDateFormat">  
  14. <!-- 在注入构造参数时,如果只有一个字符串类型的参数,  
  15. 则可省略index与type属性 -->  
  16. <constructor-arg value="yyyy年MM月dd hh时mm分ss秒" />  
  17. </bean>  
  18. <!-- 使用单例模式装配Date实例 -->  
  19. <bean id="now" class="java.util.Date"/>  
  20. <!-- 使用单例模式装配Random实例 -->  
  21. <bean id="random" class="java.util.Random"/>  
  22. <!-- 使用原型模式装配User实例,  
  23. 每次调用时都会生成一个全新的User实例 -->  
  24. <bean id="user" class="test.spring.bean.User" scope="prototype"/>  
  25. <!-- 使用单例模式装配XmlIocBean实例,  
  26. 实例属性通过Annotation注解方式注入 -->  
  27. <bean id="annotationIocBean" class="test.  
  28. spring.bean.AnnotationIocBean" />  
  29. </beans> 

最后编写AnnotationIocBean类的Junit测试用例testAnnotationIocBean:

  1. package test.spring.junit;  
  2. import org.junit.BeforeClass;  
  3. import org.junit.Test;  
  4. import org.springframework.context.support.  
  5. AbstractApplicationContext;  
  6. import org.springframework.context.support.  
  7. ClassPathXmlApplicationContext;  
  8. import test.spring.bean.AnnotationIocBean;  
  9. /** 业务控制器AnnotationIocBean的测试用例 */ 
  10. public class testAnnotationIocBean {  
  11. static AbstractApplicationContext cxt;  
  12. static AnnotationIocBean annotationIocBean;  
  13. //初始化ApplicationContext容器  
  14. @BeforeClass 
  15. public static void setUpBeforeClass() throws Exception {  
  16. //使用ClassPathXmlApplicationContext方式初始化ApplicationContext容器  
  17. cxt = new ClassPathXmlApplicationContext("applicationContext.xml");  
  18. //从Bean工厂容器中获取名为"annotationIocBean"的AnnotationIocBean实例  
  19. annotationIocBean = (AnnotationIocBean)cxt.getBean("annotationIocBean");  
  20. }  
  21. //测试AnnotationIocBean的execute方法  
  22. @Test 
  23. public void testExecute() {  
  24. annotationIocBean.execute();  
  25. //手动关闭Sping容器  
  26. cxt.close();  
  27. }  

测试用例的运行效果如图6-10所示。

分享到:
评论

相关推荐

    基于java的企业级应用开发:Bean的装配方式.ppt

    本节将详细介绍基于XML、注解(Annotation)以及自动装配这三种Bean装配方式。 首先,我们来理解什么是Bean的装配。Bean的装配,也称为依赖注入,是指将对象所需的依赖关系(例如其他对象或服务)设置到该对象中,...

    4Spring自动装配——annotation resource方式

    在Spring框架中,自动装配(Auto-Wiring)是一种简化依赖注入(Dependency Injection,DI)配置的方式,它允许Spring容器自动管理Bean之间的依赖关系。本文将深入探讨如何通过注解(Annotation)和`@Resource`来实现...

    Spring Boot技术知识点:Bean装配1

    7. **条件注解(Conditional Annotation)**:Spring Boot提供了如@ConditionalOnClass、@ConditionalOnBean、@ConditionalOnMissingBean等注解,使得Bean的创建基于某些条件。例如,@ConditionalOnClass只有在类...

    S2SH整合基于annotation

    Spring的Annotation支持如`@Autowired`用于自动装配bean,`@Service`、`@Repository`和`@Controller`来标记不同类型的组件。Spring还提供了一整套事务管理,通过Annotation可以轻松控制事务的边界,如`@...

    详解Spring基于Annotation的依赖注入实现

    在深入探讨Spring框架中基于注解(Annotation)的依赖注入(Dependency Injection,简称DI)实现之前,我们首先需要理解几个核心概念:Spring框架、依赖注入、以及注解本身。 ### Spring框架简介 Spring框架是一个...

    详解Spring中Bean的生命周期和作用域及实现方式

    Spring框架提供了多种方式来实现Bean,例如使用XML配置文件、使用Annotation配置等。 1. 使用XML配置文件:可以在XML配置文件中配置Bean的生命周期和作用域。 2. 使用Annotation配置:可以使用Annotation来配置Bean...

    基于Annotation的MVC框架SSH示例.rar

    在这个"基于Annotation的MVC框架SSH示例"中,我们将探讨如何使用注解(Annotation)来简化SSH框架的配置和实现。 1. **Spring框架**:Spring是核心容器,负责管理应用对象的生命周期和依赖注入。在传统的Spring配置...

    ssh包(基于annotation)

    例如,@Autowired注解可以自动装配bean,@Service、@Repository和@Controller则用于标记不同层的服务类。Spring AOP通过注解如@Aspect和@Pointcut,实现切面编程,简化事务管理和日志记录等。 Struts2是SSH中的MVC...

    jar包_javax.annotation.zip

    在Java EE环境中,Bean装配通常通过XML配置文件、注解或者编程方式来完成。而在Spring框架中,除了XML配置外,更倾向于使用注解来简化装配过程,`@Resource`就是其中的一个重要注解。它简化了服务的查找和注入,提高...

    IOC之基于Java类的配置Bean

    基于Java类的配置Bean是Spring实现IOC的一种方式,与XML配置相比,提供了更灵活和类型安全的选项。 在Spring中,我们可以通过编写Java类来定义Bean的配置,这种配置方式通常被称为JavaConfig。这种方式的优点在于...

    基于框架的Web开发-装配Bean自动装配.doc

    在基于框架的Web开发中,Spring框架的自动化装配(Auto-Wiring)是核心特性之一,它极大地简化了Java应用程序的依赖管理。Spring通过组件扫描(Component Scanning)和自动装配(Autowiring)来实现这一目标,使得...

    基于annotation的SSH整合

    - `@Autowired`:用于自动装配bean的依赖,Spring会根据类型或属性名找到合适的bean进行注入。 - `@Qualifier`:当有多个相同类型的bean时,可以使用此注解指定特定的bean。 - `@Transactional`:用于声明方法为事务...

    Spring实现自动装配

    2. **基于类型的自动装配(By Type Auto-Wiring)**:这是最常用的自动装配方式,Spring会查找与目标bean类型匹配的bean,并将其注入。如果有多个匹配的bean,Spring会抛出异常。可以在bean定义中使用`autowired`...

    动态的装配bean,注入到Controller中

    总结,动态装配bean到Controller有XML配置和Java注解两种方式。XML方式适用于传统配置,而`@PostConstruct`注解方式则提供了更简洁、更面向Java的方式。在实际项目中,根据团队习惯和项目需求,可以选择适合的方式来...

    SSH2增删改查的项目基于Annotation

    在这个基于Annotation的SSH2增删改查项目中,我们将深入探讨这三个框架如何协同工作,以及如何利用注解简化开发过程。 1. **Struts2**: Struts2是MVC(Model-View-Controller)设计模式的实现,负责处理HTTP请求...

    3Spring使用annotation方式autowire

    本篇将详细探讨"3Spring使用annotation方式autowire"这一主题,包括注解驱动的自动装配(Autowiring)以及相关的源码分析。 ### 一、注解驱动的自动装配 自动装配是Spring框架的一个核心特性,它允许框架自动管理...

    Spring的Autowired自动装配(XML版本+Annotation版本+源码+解析)

    @Autowired是Spring框架中的一个核心注解,用于实现自动装配bean的需求。当我们想要在类中注入某个依赖时,不再需要手动通过setter方法或构造函数进行设置,而是通过@Autowired来自动完成。这种特性极大地提高了代码...

Global site tag (gtag.js) - Google Analytics