Spring如何对私有接口进行注入(转载)

来自:http://didiluck.iteye.com/blog/1779640

Spring 标注@Autowired 如果做到自动装配私有变量而不使用set方法的原理 

熟悉jdk的话就知道,方法就是使用java.lang.reflect.Field类的:Field.setAccessible(true); 将字段设置为'true',就可以直接使用set方法为其赋值了。 

如果不设置'true'的话,则会抛出'java.lang.IllegalAccessException'的异常 

Spring中的代码如下(标绿的部分): 
------------------------------------------------------------------------------------------------------------------ 

          /** 
          * Either this or {@link #getResourceToInject} needs to be overridden. 
          */ 
          protected void inject(Object target, String requestingBeanName, PropertyValues pvs) throws Throwable {
               if (this.isField) { 
                    Field field = (Field) this.member; 
                    ReflectionUtils.makeAccessible(field); 
                    field.set(target, getResourceToInject(target, requestingBeanName)); 
               } 
               else { 
                    if (checkPropertySkipping(pvs)) { 
                         return; 
                    } 
                    try { 
                         Method method = (Method) this.member; 
                         ReflectionUtils.makeAccessible(method); 
                         method.invoke(target, getResourceToInject(target, requestingBeanName)); 
                    } 
                    catch (InvocationTargetException ex) { 
                         throw ex.getTargetException(); 
                    } 
               } 
          } 

 

 

说明:Field.setAccessible(true);这个方法是从它的父类继承的,也就是java.lang.reflect.AccessibleObject类。

关于这个类的说明:

AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor 对象来设置或获得字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。

在反射对象中设置 accessible 标志允许具有足够特权的复杂应用程序(比如 Java Object Serialization 或其他持久性机制)以某种通常禁止使用的方式来操作对象。

 

setAccessible方法

public void setAccessible(boolean flag)

throws SecurityException

将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。

首先,如果存在安全管理器,则在 ReflectPermission("suppressAccessChecks") 权限下调用 checkPermission 方法。

如果 flag 为 true,并且不能更改此对象的可访问性(例如,如果此元素对象是 Class 类的 Constructor 对象),则会引发 SecurityException。

如果此对象是 java.lang.Class 类的 Constructor 对象,并且 flag 为 true,则会引发 SecurityException。

原文地址:https://www.cnblogs.com/xiaolang8762400/p/7309429.html