问题描述:
Annotation or xml? 从Spring2.0以后的版本中,Spring也引入了基于注解(Annotation)方式的配置,开发人员对注解(Annotation)的态度也是萝卜青菜各有所爱,个人认为注解可以大大简化配置,提高开发速度,同时也不能完全取代XML配置方式,XML方式更加灵活,并且发展的相对成熟,这种配置方式为大多数 Spring 开发者熟悉;注解方式使用起来非常简洁,但是尚处于发展阶段,XML配置文件和注解(Annotation)可以相互配合使用。
注解其实也没什么神秘的,和XML配置文件类似都是一种配置的方式而已,只不过利用JDK的反射机制,在编译时或者运行时动态获取所配置的信息而已,注解本身只是个标识,注解的真正意义在于通过注解标识获取注解所在对象的信息以及注解中配置的信息。
Spring的注解方式只是简化了XML配置文件,在读入Bean定义资源时可以动态扫描给定的路径,在解析和依赖注入时,XML方式配置的Bean,Spring需要解析XML文件,注解方式配置的Bean,Spring需要通过JDK的反射机制获取注解配置的信息。
具体实现:
1.导入spring-context-2.5.xsd的jar包,同时xml文件里新增xsd元数据文件
Eclipse的XML catalog里添加spring-context-2.5.xsd元数据文件
<?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="u" class="com.dao.impl.UserDaoImpl" scope="prototype"> </bean> <bean id="userService" class="com.service.UserService" autowire="byType" init-method="init" destroy-method="destroy" scope="prototype"> </bean> </beans>中间加这一句,指XML文件的命名空间(namespace—ns)中以context开头的可以写的内容去标识的网站http://www.springframework.org/schema/context里找。
2.@Autowired 注解 @Autowired 注解可以用于“传统的”setter 方法,也可以用于以属性为参数/多个参数的方法。 Autowired注解 a) 默认按类型byType注入 b) 如果想用byName,使用@Qulifier c) 写在private field(第三种注入形式)(不建议,破坏封装) d) 如果写在set上,@qualifier需要写在参数上
UserService的setUserDao中增加@Autowired注解,注入userDao的bean。
@Autowired public void setUserDao(UserDao userDao) { this.userDao = userDao; }3.测试类
@Test public void testAdd() throws Exception { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); UserService service = (UserService) ctx.getBean("userService"); service.add(new User()); }运行时报错
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [beans.xml]; nested exception is java.lang.IllegalStateException: Context namespace element 'annotation-config' and its parser class [org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser] are only available on JDK 1.5 and higher主要是由于spring-framework-2.5.6 不支持泛型,可以将spring的jar升级为3.0版本或将jdk版本降级【在该项目properties中配置低版本jdk即可】
4.用Qualifier指定bean的id AutowiredAnnotationBeanPostProcessor默认以byType方式注入bean,如果出现了两个类型相同的bean,则需要@Qualifier注解。
@Overwrite这种注解是JVM虚拟机处理,而@Autowired不是JVM处理的,是由以下四个bean处理的。 (隐式注册 post-processors 包括了 AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,也包括了前面提到的 RequiredAnnotationBeanPostProcessor。)
XML文件:
<bean id="u" class="com.dao.impl.UserDaoImpl"> </bean> <bean id="u2" class="com.dao.impl.UserDaoImpl"> </bean>【配置windows-perferences-editor-content assist的Auto Activition值为200、.@与#即可出现@后的提示】
UserService.java用Qualifier注解指定bean的id
@Autowired public void setUserDao(@Qualifier("u") UserDao userDao) { this.userDao = userDao; }同时,@Required注解跟@Overwrite一样,写不写都行。
再次强调,spring开发手册很重要,要学会怎么学习与使用开发手册
