Spring基于annotation的依赖注入实现
2015-05-27 16:16
423 查看
Spring基于annotation的依赖注入实现
一、工作目的
以前通常我们将Action、Service、Dao层的对象都以配置文件的形式交给Spring管理,Spring将各层的对象以松耦合的方式组织在一起,Action对象无须关心Service对象的具体实现,Service对象无须关心持久层对象的具体实现,各层对象的调用完全面向接口。当系统需要重构时,代码的改写量将大大减少。不过上述方式有一定的局限性,试想我们的系统规模比较大的时候,需要交给Spring管理的Bean数量庞大,如果都写在Spring配置文件applicationContext.xml中,代码的可读性、可维护性会变得很差。本例将简要介绍Spring中常使用的annotation,并以演示通过annotation的方式完成Spring的依赖注入。
二、具体内容及步骤
Spring3.0 以前,使用 XML 进行依赖配置几乎是唯一的选择。Spring 3.0 的出现改变了这一状况,它提供了一系列的针对依赖注入的注解,这使得Spring IoC 在 XML 文件之外多了一种可行的选择。1、将类标识为 Bean
使用@Repository、@Service、@Controller和@Component,@Repository 注解属于最先引入的一批,它用于将数据访问层 (DAO 层 ) 的类标识为 Spring Bean。具体只需将该注解标注在 DAO 类上即可。同时,为了让 Spring 能够扫描类路径中的类并识别出 @Repository 注解,需要在 XML 配置文件中启用 Bean 的自动扫描功能,这可以通过 <context:component-scan/>
实现。如下所示:
<span style="font-family:Times New Roman;"><!-- Spring搜索路径配置,如下配置将搜索工程com目录下标识的Bean--> <context:annotation-config /> <context:component-scan base-package="com" > </context:component-scan></span>
这样我们不再需要在XML中显式使用 <bean/> 进行 Bean 的配置。Spring 在容器初始化时将自动扫描 base-package 指定的包及其子包下的所有 class 文件,所有标注了@Repository、@Service、@Controller、@Component 的类都将被注册为 Spring Bean。
●@Component 是一个泛化的概念,仅仅表示一个组件 (Bean) ,可以作用在任何层次。
●@Service 通常作用在业务层,但是目前该功能与 @Component 相同。
●@Constroller 通常作用在控制层,但是目前该功能与 @Component 相同。
●@Repository 通常用在持久层,但是目前该功能与 @Component 相同。
通过在SSH框架不同层的类上使用 @Repository、@Service 和 @Constroller 注解,Spring 会自动创建相应的 BeanDefinition 对象,并注册到 ApplicationContext 中。这些类就成了 Spring 受管组件。通常在程序中,为了便于开发,各层都使用@Component进行注解,如图:
@Component("staffDao") public class staffDaoImp implements staffDao{ /*...代码...*/ }
通常使用"name"的形式生成Bean的名称,还有一种方式实现 BeanNameGenerator 接口,确认包含了一个默认的无参数构造方法。然后在配置扫描器时使用属性name-generator.使用Spring管理Bean默认作用域的是singleton,容器中只存在一个实例,也可以通过@Scope指定作用域为prototype,容器在接受到请求的时候,会每次都重新生成一个新的对象给请求方。
2、指定 Bean 的自动装配策略
自动装配是指,Spring在装配Bean的时候,根据指定的自动装配规则,将某个Bean所需要引用类型的Bean注入进来。通常使用 @Resource、@Autowired 和@Qualifier。
①@Autowired 和 @Qualifier
使用 @Autowired 注解进行装配,只能是根据类型进行匹配。@Autowired 注解可以用于 Setter 方法、构造函数、字段,甚至普通方法,前提是方法必须有至少一个参数。@Autowired 标注作用于普通方法时,会产生一个副作用,就是在容器初始化该 Bean 实例的时候就会调用该方法。当然,前提是执行了自动装配,对于不满足装配条件的情况,该方法也不会被执行。此时与@Qualifier的配合使用可以实现根据Bean的byName自动注入,例如:
@Autowired @Qualifier("personDaoBean") private PersonDao personDao;
如图代码:如果不使用@Qualifier指定要装配的Bean名称,Spring会将容器里类型为PersonDao的Bean装配给该类(根据类型装配原则),当然通过代码的控制可以实现业务的要求,不过各层的耦合会比较严重,不符合Spring松耦合的理念,通常推荐@Autowired、@Qualifier配合使用完成ByName装配,下面将介绍更方便的byName装配方式,@Resource。
②@Resource
如果希望根据 name 执行自动装配,那么应该使用JSR-250提供的@Resource 注解,而不应该使用@Autowired与@Qualifier的组合。@Resource使用 byName 的方式执行自动封装。@Resource 标注可以作用于带一个参数的 Setter 方法、字段,以及带一个参数的普通方法上。@Resource 注解有一个 name 属性,用于指定Bean在配置文件中对应的名字。如果没有指定name属性,那么默认值就是字段或者属性的名字。@Resource和@Qualifier的配合虽然仍然成立,但是
@Qualifier对于@Resource而言,几乎与name属性等效。如下:
@ Resource (name="personDaoBean") private PersonDao personDao;
3、实例演示
①Spring配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- Spring搜索路径配置 --> <context:annotation-config /> <context:component-scan base-package="com" > </context:component-scan> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"> </property> <property name="url" value="jdbc:mysql://localhost:3306/hibernate_cascade_query"></property> <property name="username" value="root"></property> <property name="password" value="123123"></property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" p:dataSource-ref="dataSource" p:configLocation="classpath:config/hibernate.cfg.xml" > </bean> </beans>
通过配置文件可以看出,我们不再像之前SSH框架搭建例子里,使用:
<bean id="userDao" class="com.dao.imp.userDaoImp"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean>
的方式,在配置文件中完成依赖注入。hibernate配置文件、日志文件的配置同SSHSSH框架搭建Demo里面相同,不再赘述。
②Dao实现层
@Component("staffDao") public class staffDaoImp implements staffDao{ @Resource private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } /* ...code... */用到的第一个annotation,@Component("staffDao")将class staffDaoImp类标识为Bean交给Spring管理,staffDao为该Bean 的名字。当程序运行的时候,读Spring配置文件,根据:
<context:annotation-config /> <context:component-scan base-package="com" > </context:component-scan>
搜索com目录,将Component标识的Bean注入到Spring容器。@Resource没有指定name属性,默认值是字段或者属性的名字即装配Spring容器中名为sessionFactory的Bean,sessionFactory的注入是通过配置文件的方式完成的。一般情况下,系统级的Bean通过配置文件的方式注入,业务级的Bean通过annotation注入。
③Service实现层
@Component("staffService") public class staffServiceImp implements staffService{ @Resource(name="staffDao") private staffDao staffDao; public staffDao getStaffDao() { return staffDao; } public void setStaffDao(staffDao staffDao) { this.staffDao = staffDao; } /* ...code... */
@Component("staffService")的功能是将class staffServiceImp类交给Spring容器管理,@Resource(name="staffDao")的作用装配名为staffDao的Bean,面前我们已经将staffDaoImp类标识为staffDao并注入到了Spring容器。name属性值必须与之前注入的保持一致。
④Action层
@Component("staffAction") public class staffAction extends ActionSupport implements ServletRequestAware, ServletResponseAware { private static final long serialVersionUID = 1L; private HttpServletRequest request; private HttpServletResponse response; @Resource(name="staffService") private staffService staffService; private String staffName; /* staffService的Getter()、Setter() .... */
@Resource(name="")也可以放到Setter()方法之上:
public staffService getStaffService() { return staffService; } @Resource(name="staffService") public void setStaffService(staffService staffService) { this.staffService = staffService; }
两种方法的效果是相同的,可以根据自己的习惯,选择性使用
相关文章推荐
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现(转)
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现(二)
- 详解Spring3基于Annotation的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- Spring 3.0 基于Annotation的依赖注入实现详解
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现--转载
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现