使用@Autowired注解完成属性依赖注入时,写在属性上与写在set方法上的区别

         @Autowired 注解可以对成员变量、构造方法、方法进行标注,来完成自动装配工作;放在成员变量上,也可以放在成员变量的set()方法上,也可以放在任意方法上表示自动执行当前方法,如果方法有参数,会在IOC容器中自动寻找同类型参数为其传值。

         需要明确的是:@Autowired 是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Qualifier使用;

         当@Autowired 注解放在成员变量上时,不需要写成员变量的getter、setter方法;如下代码所示:

@Service("repairService")
public class RepairServiceImpl implements RepairServiceI {
	@Autowired
	private MenuDaoI menuDao;
	
	private UserDaoI userDao;
	public UserDaoI getUserDao() {
		return userDao;
	}
	@Autowired
	public void setUserDao(UserDaoI userDao) {
		this.userDao = userDao;
	}

}

       当使用@Autowired 注解时,不写对应getter、setter方法,Spring会通过Java的“反射机制”来实现属性的依赖注入:

       Java允许用户关闭【属性】或者【方法】的【访问权限】;也就是说,本来你的属性或者方法声明了【private】,在访问类中的这个private标识的某个属性时,Java首先会进行一个【安全检查】,确认以下你要访问的这个属性的访问权限是什么,如果是【public】,那么就直接访问;如果是【private】,则不能访问该类中的私有属性。

       按照正常的操作是这样的,但是Java还提供了一个方法,能够让你关闭属性或者方法的【访问控制权限】,比如即使声明了某个属性是private的,但是仍然还是可以通过【类.属性】的方式直接访问这个私有属性。这就是反射框架中:

   

        对此方法的介绍如下,官方文档说明:

          重点是,从官方文档可以看出,我们所有的【构造器】、【属性】、【方法】原来都是 【AccessibleObject 】类的子类!!!那么我们的【属性】能够更改【访问控制权限】,是不是在它的父类【AccessibleObject】中有实现了逻辑呢?官方文档中对 setAccessible(boolean flag) 方法的作用介绍如下:

Set the accessible flag for this object to the indicated boolean value. A value of true indicates that the reflected object should suppress Java language access checking when it is used. A value of false indicates that the reflected object should enforce Java language access checks.

其意思是说,将此对象的【可访问标识】设置为用户指定的值 ( true或者false)。如果该对象的【可访问标识】被设置成了【true】,那么该对象在使用时将不会进行【访问控制权限】的安全性检查;相反,如果被设置成了【false】,则在访问该对象时,应当要求Java强制对其对象的【访问控制权限】进行检查。

       原来Spring会将我们用 @Autowired 注解标识过的属性/成员变量的【访问控制检查】关闭掉,即对每个属性进行了【setAccessible(true)】的设置,导致这些属性即使我们设定了【private】权限,Spring却仍然能够不通过 getter 和 setter 方法来访问这些属性,达到一定的目的。对于开发者来说,就不用写 setter 和getter 方法了。

至此,想起某个项目视频教程中的老师有讲到使用 @Autowired 注解实现依赖注入的以上两种实现方式的区别:当将 @Autowired 注解直接写在成员变量上时,即使设定该成员变量的访问权限为private,那么也会自动将其改变成public;而将 @Autowired 注解写在成员变量的 setter 方法上则不会出现此问题。所以不建议使用前者!!!

你可能感兴趣的:(SpringMVC)