spring如何实现这项技术?

kev*_*vin 1 java spring

今天,我了解到我们可以使用spring的@AutoWired注释来完成自动注入,@ AutoWired可以在很多条件下使用,比如

@AutoWired
public void setInstrument(Instrument instrument){
  this.instrument = instrument;
}
Run Code Online (Sandbox Code Playgroud)

但我们也可以把这个@AutoWired放在私人领域

@AutoWired
private Instrument instrument;
Run Code Online (Sandbox Code Playgroud)

我想知道,春天如何将一个对象注入私有领域,我知道我们可以使用java的反射来获取一些元数据,当我使用反射在私有字段上设置一个对象时,这里出现了一个问题,以下是堆栈跟踪

 java.lang.IllegalAccessException: Class com.wire.with.annotation.Main can not access a member of class com.wire.with.annotation.Performer with modifiers "private"
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下吗?为什么spring可以将一个对象注入一个没有setter方法的私有字段.非常感谢

vik*_*ngh 7

这是使用您需要Filed.setAccessible(true)访问private字段的反射来完成的.

privateField.setAccessible(true);//works ,if java security manager is disable
Run Code Online (Sandbox Code Playgroud)

更新: -

例如-

public class MainClass {
    private String string="Abcd";

    public static void main(String... arr) throws SecurityException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchFieldException{
        MainClass mainClass=new MainClass();
        Field stringField=MainClass.class.getDeclaredField("string");
        stringField.setAccessible(true);//making field accessible 
        /*if SecurityManager enable then,  
        java.security.AccessControlException: access denied will be thrown here*/
        stringField.set(mainClass, "Defgh");//seting value to field as it's now accessible
        System.out.println("value of string ="+stringField.get(mainClass));//getting value from field then printing it on console
    }
}
Run Code Online (Sandbox Code Playgroud)

Java安全管理器(如果启用)也会阻止Spring访问私有字段

  • 只有在安全经理不禁止的情况下. (5认同)
  • @Uwe如果安全经理禁止它,Spring DI不起作用. (3认同)