`
haowei0315
  • 浏览: 34519 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring2.5中基于注释的IoC

阅读更多

 基于注释(Annotation)的配置有越来越流行的趋势,Spring 2.5 顺应这种趋势,提供了完全基于注释配置 Bean、装配 Bean 的功能,您可以使用基于注释的 Spring IoC 替换原来基于 XML 的配置。

  

   注释的优势

       它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO 的属性名、类型等信息,如果关系表字段和 PO 属性名、类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过 Java 反射机制获取。
       注释和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和 Java 代码放在一起,有助于增强程序的内聚性。而采用独立的 XML 配置文件,程序员在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低开发效率。
      

       因此在很多情况下,注释配置比 XML 配置更受欢迎,注释配置有进一步流行的趋势。Spring 2.5 的一大增强就是引入了很多注释类,现在您已经可以使用注释配置完成大部分XML 配置的功能。在这篇文章里,我们将向您讲述使用注释进行 Bean 定义和依赖注入的内容。

    原来我们是怎么做的

UserDAO.java:

package com.tanlan.springdemo;
/**
 * UserDAO接口
 * 
 * @author tanlan tl_smile@163.com
 * 
 * @date 2009-8-3
 */
public interface UserDAO {
	public void addUser();
}

 

 UserJDBCDAO.java:

package com.tanlan.springdemo;
/**
 * UserDAO的JDBC实现
 * 
 * @author tanlan tl_smile@163.com
 * 
 * @date 2009-8-3
 */

public class UserJDBCDAO implements UserDAO {
	public void addUser() {
		System.out.println("使用JDBC增加用户信息!");
	}

}

 

UserService.java:

package com.tanlan.springdemo;
/**
 * User业务逻辑处理类
 * 
 * @author tanlan tl_smile@163.com
 * 
 * @date 2009-8-3
 */
public class UserService {
	private UserDAO userDAO;

	public void addUser() {
		userDAO.addUser();
	}

	public UserDAO getUserDAO() {
		return userDAO;
	}

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

}

 配置文件 spring.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
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	<bean id="userJdbcDAO" class="com.tanlan.springdemo.UserJDBCDAO"></bean>
	<bean id="userService" class="com.tanlan.springdemo.UserService">
		<property name="userDAO" ref="userJdbcDAO"></property>
	</bean>
</beans>

 测试类Test.java:

package com.tanlan.springdemo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

	public static void main(String[] args) {
		String[] files = { "spring.xml" };
		ApplicationContext context = new ClassPathXmlApplicationContext(files);
		UserService userService = (UserService) context.getBean("userService");
		userService.addUser();
	}

}

 

使用 @Autowired 注释

          Spring 2.5 引入了 @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。

 

对UserService.java的改进:

package com.tanlan.springdemo;

import org.springframework.beans.factory.annotation.Autowired;

/**
 * User业务逻辑处理类
 * 
 * @author tanlan tl_smile@163.com
 * 
 * @date 2009-8-3
 */
public class UserService {
	@Autowired
	private UserDAO userDAO;

	public void addUser() {
		userDAO.addUser();
	}
}

 

这个类甚至可以省略getter/setter.

 

  配置文件spring.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
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"></bean>
	<bean id="userJdbcDAO" class="com.tanlan.springdemo.UserJDBCDAO"></bean>
	<bean id="userService" class="com.tanlan.springdemo.UserService"></bean>
</beans>

 

      Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。

        UserService类的属性不需要配置了。

当候选 Bean 数目不为 1 时的应对方法

        在默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。
       和找不到一个类型匹配 Bean 相反的一个错误是:如果 Spring 容器中拥有多个候选Bean,Spring 容器在启动时也会抛出 BeanCreationException 异常。
       Spring 允许我们通过 @Qualifier 注释指定注入 Bean 的名称

加入现在多了一个UserDAO的实现类

UserHibernateDAO.java:

package com.tanlan.springdemo;

/**
 * UserDAO的Hibernate实现
 * 
 * @author tanlan tl_smile@163.com
 * 
 * @date 2009-8-3
 */
public class UserHibernateDAO implements UserDAO {
	public void addUser() {
		System.out.println("使用Hibernate增加用户信息!");
	}
}

 

更新spring.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
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"></bean>
	<bean id="userJdbcDAO" class="com.tanlan.springdemo.UserJDBCDAO"></bean>
	<bean id="userHibernateDAO" class="com.tanlan.springdemo.UserHibernateDAO"></bean>
	<bean id="userService" class="com.tanlan.springdemo.UserService"></bean>
</beans>

 

当Spring自动找寻UserDAO类型的类时,会找到两个符合要求的类:

 No unique bean of type [com.tanlan.springdemo.UserDAO] is defined: expected single matching bean but found 2: [userJdbcDAO, userHibernateDAO]

 

需要改进UserService.java:

package com.tanlan.springdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

/**
 * User业务逻辑处理类
 * 
 * @author tanlan tl_smile@163.com
 * 
 * @date 2009-8-3
 */
public class UserService {
	@Autowired
	@Qualifier("userJdbcDAO")
	private UserDAO userDAO;

	public void addUser() {
		userDAO.addUser();
	}
}

 

使用 <context:annotation-config/> 简化配置

        Spring 2.1 添加了一个新的 context 的 Schema 命名空间,该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置.

       改进spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
	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
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	<context:annotation-config></context:annotation-config>
	<bean id="userJdbcDAO" class="com.tanlan.springdemo.UserJDBCDAO"></bean>
	<bean id="userHibernateDAO" class="com.tanlan.springdemo.UserHibernateDAO"></bean>
	<bean id="userService" class="com.tanlan.springdemo.UserService"></bean>
</beans>

 注意命名空间:xmlns:context=http://www.springframework.org/schema/context的添加。

以及<context:annotation-config/>的使用。

使用 @Component

 Spring 2.5 提供的 @Component 注释可以定义 Bean,从 XML 配置文件中完全移除 Bean 定义的配置。

改进UserJDBCDAO.java:

package com.tanlan.springdemo;

import org.springframework.stereotype.Component;

/**
 * UserDAO的JDBC实现
 * 
 * @author tanlan tl_smile@163.com
 * 
 * @date 2009-8-3
 */
@Component("userJdbcDAO")
public class UserJDBCDAO implements UserDAO {
	public void addUser() {
		System.out.println("使用JDBC增加用户信息!");
	}

}

 

改进UserHibernateDAO.java:

package com.tanlan.springdemo;

import org.springframework.stereotype.Component;

/**
 * UserDAO的Hibernate实现
 * 
 * @author tanlan tl_smile@163.com
 * 
 * @date 2009-8-3
 */
@Component("userHibernateDAO")
public class UserHibernateDAO implements UserDAO {
	public void addUser() {
		System.out.println("使用Hibernate增加用户信息!");
	}
}

 

改进UserService.java:

package com.tanlan.springdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
 * User业务逻辑处理类
 * 
 * @author tanlan tl_smile@163.com
 * 
 * @date 2009-8-3
 */
@Component
public class UserService {
	@Autowired
	@Qualifier("userJdbcDAO")
	private UserDAO userDAO;

	public void addUser() {
		userDAO.addUser();
	}
}

 

改进spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
	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
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	<context:component-scan base-package="com.tanlan.springdemo"></context:component-scan>
</beans>

 

      在使用 @Component 注释后,Spring 容器必须启用类扫描机制以启用注释驱动 Bean 定义和注释驱动 Bean 自动注入的策略.
       <context:component-scan/> 的 base-package 属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理.

注释配置和 XML 配置的适用场合

       是否有了这些 IOC 注释,我们就可以完全摒除原来 XML 配置的方式呢?答案是否定的。有以下几点原因:
       注释配置不一定在先天上优于 XML 配置。如果 Bean 的依赖关系是固定的,(如Service 使用了哪几个 DAO 类),这种配置信息不会在部署时发生调整,那么注释配置优于 XML 配置;反之如果这种依赖关系会在部署时发生调整,XML 配置显然又优于注释配置,因为注释是对 Java 源代码的调整,您需要重新改写源代码并重新编译才可以实施调整。
如果 Bean 不是自己编写的类(如 JdbcTemplate、SessionFactoryBean 等),注释配置将无法实施,此时 XML 配置是唯一可用的方式。
       注释配置往往是类级别的,而 XML 配置则可以表现得更加灵活。比如相比于@Transaction 事务注释,使用 aop/tx 命名空间的事务配置更加灵活和简单。
      

       所以在实现应用中,我们往往需要同时使用注释配置和 XML 配置,对于类级别且不会发生变动的配置可以优先考虑注释配置;而对于那些第三方类以及容易发生调整的配置则应优先考虑使用 XML 配置。Spring 会在具体实施 Bean 创建和 Bean 注入之前将这两种配置方式的元信息融合在一起。

 

 

 

 

分享到:
评论

相关推荐

    使用Spring2.5的Autowired实现注释型的IOC

    "使用Spring2.5的Autowired实现注释型的IOC" 在Java开发中,IOC(Inversion of Control,控制反转)是一种常见的设计模式,它可以将对象之间的耦合关系解耦合,使得系统更加灵活和可维护。在Spring框架中,IOC是...

    spring2.5 注解

    使用Spring2.5的Autowired实现注释型的IOC , 使用Spring2.5的新特性——Autowired可以实现快速的自动注入,而无需在xml文档里面添加bean的声明,大大减少了xml文档的维护

    Struts2+Spring2.5+Ibatis2.3架构

    Struts2+Spring2.5+Ibatis2.3架构是一种经典的Java Web开发技术栈,广泛应用于企业级应用系统中。这个架构结合了Struts2的MVC框架、Spring的依赖注入(DI)和面向切面编程(AOP)以及Ibatis的持久层解决方案,为...

    使用 Spring 2_5 注释驱动的 IoC 功能.mht

    **Spring 2.5 注释驱动的 IoC 功能详解** Spring 框架自 2.5 版本开始引入了对注解的强大支持,极大地简化了依赖注入(Dependency Injection,简称 DI)的配置过程。注解驱动的 IoC(Inverse of Control,控制反转...

    springMVC详解以及注解说明 中文WORD版.rar

    基于注释(Annotation)的配置有越来越流行的趋势,Spring 2.5 顺应这种趋势,提供了完全基于注释配置 Bean、装配 Bean 的功能,您可以使用基于注释的 Spring IoC 替换原来基于 XML 的配置。本文通过实例详细讲述了 ...

    关于spring boot中几种注入方法的一些个人看法

    在 Spring 2.5 引入了 @Autowired 注释,我们平常直接引用的时候很少注意这些,只是自己写好了一个方法或者 springboot 自动配置好的一个方法我们要在另一个类中去调用,这个时候,我们就会采用该注释。 2. @...

    Spring Annotaion Support详细介绍及简单实例

    例如,在Spring 2.5版本中,引入了@Component、@Service、@Repository和@Controller等注解,用于标记不同的组件和服务层,使得Spring的依赖注入和AOP等功能更加简洁易用。 开发者可以在任何Java类上使用这些注解来...

    Spring Framework 中文

    在Spring中,由Spring容器负责控制程序之间的关系,而非传统实现中由程序代码直接控制。 ##### 1.2 模块划分 Spring框架被划分为多个模块,这些模块可以单独使用也可以一起使用,具体如下: - **1.2.1 核心容器...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    主要包括Java Web开发环境、JSP语法、JSP内置对象、Java Bean技术、Servlet技术、EL与JSTL标签库、数据库应用开发、初识Struts2基础、揭密Struts2高级技术、Hib锄劬e技术入门、Hibernate高级应用、Spring核心之IoC、...

    Java 学习路线规划图.pdf

    - 编码风格、命名规则、注释规范等。 - **文档撰写** - 技术文档、用户手册、API文档等。 **4.3 团队协作与沟通** - **版本控制** - Git、SVN等工具的使用。 - **敏捷开发** - Scrum、Kanban等敏捷实践。 - **...

Global site tag (gtag.js) - Google Analytics