@Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。在使用@Autowired之前,我们对一个bean配置起属性时,是这用用的
<property name="属性名" value=" 属性值"/>
通过这种方式来,配置比较繁琐,而且代码比较多。在Spring 2.5 引入了 @Autowired 注释
下面用案例来具体说明
UserRepository.java
package com.Autowired.learning;
public interface UserRepository {
void save();
}
这里定义了一个UserRepository接口,其中定义了一个save方法
UserRepositoryImps.java
package com.Autowired.learning;
import org.springframework.stereotype.Repository;
@Repository(value="userRepositoryImps")
public class UserRepositoryImps implements UserRepository{
@Override
public void save() {
System.out.println("UserRepositoryImps save");
}
}
定义一个UserRepository接口的实现类,并实现save方法,在这里指定了该bean在IoC中标识符名称为userRepository
UserService.java
package com.Autowired.learning;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
@Qualifier("userJdbcImps")
private UserRepository userRepository;
public void save(){
userRepository.save();
}
}
applicationContext.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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.Autowired.learning" />
</beans>
测试代码:
package com.Autowired.learning;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.junit.Test;
public class MyTest {
@Test
public void myTest1(){
ApplicationContext ctx=new ClassPathXmlApplicationContext("com/Autowired/learning/applicationContext.xml");
UserService userService=(UserService) ctx.getBean("userService");
userService.save();
}
}
运行,效果如下
那么使用@Autowired的原理是什么?
其实在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource(是CommonAnnotationBeanPostProcessor后置处理器处理的)或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
注意事项:
在使用@Autowired时,首先在容器中查询对应类型的bean
如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
如果查询的结果不止一个,那么@Autowired会根据名称来查找。
如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false
举例说明:
在上面例子中,我们再定义一个类来实现UserRepository接口
UserJdbcImps.java
package com.Autowired.learning;
import org.springframework.stereotype.Repository;
@Repository(value="userJdbcImps")//这个value值可以随便取的,然后再service调用的时候需要和这个值对应
public class UserJdbcImps implements UserRepository{
@Override
public void save() {
System.out.println("UserJdbcImps save");
}
}
这时在启动容器后,在容器中有两个UserRepository类型的实例,一个名称为userRepository,另一个为userJdbcImps。在UserService中
可以根据@Qualifier标记,来指定需要装配bean的名称,代码这样写
package com.Autowired.learning;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
@Qualifier("userJdbcImps") //这个注解里面的值可以选择实现的@Repository类
// @Qualifier("userRepositoryImps")
private UserRepository userRepository;
public void save(){
userRepository.save();
}
}
输出
如果换成,下面那个注解
package com.Autowired.learning;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
// @Qualifier("userJdbcImps") //这个注解里面的值可以选择实现的@Repository类
@Qualifier("userRepositoryImps")
private UserRepository userRepository;
public void save(){
userRepository.save();
}
}
运行,效果如下
因此,我们要养成一个好的习惯,那就是要在注解里面写上value值