2013-07-16 66 views
1

,我了解到,我们可以在一个私有字段使用Spring的@Autowired注解来完成自动注射, @Autowired可以在许多条件下使用,如Spring如何实现该技术?今天

@AutoWired 
public void setInstrument(Instrument instrument){ 
    this.instrument = instrument; 
} 

,但我们也可以把@AutoWired,这样

@AutoWired 
private Instrument instrument; 

我想知道,怎么可能春天注入的对象为私人领域,我知道我们可以使用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" 

有的身体可以解释吗?为什么春天可以注入一个对象到私人领域而没有setter方法。非常感谢

+0

反射,BCEL等。 – zeroke

+1

它是'@ Autowired'。 –

回答

7

这是使用反射你需要Filed.setAccessible(true)来访问private字段。

privateField.setAccessible(true);//works ,if java security manager is disable 

更新: -

EG-

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 
    } 
} 

Java安全管理器(如果启用)还可以防止春季访问私有字段

+5

仅限于安全管理员禁止的情况。 –

+3

@Uwe如果安全管理员禁止它,Spring DI不起作用。 –

3

我想你忘记了设置setAccessible(true)在您尝试访问的字段上:

public class Main { 

    private String foo; 

    public static void main(String[] args) throws Exception { 
     // the Main instance 
     Main instance = new Main(); 
     // setting the field via reflection 
     Field field = Main.class.getDeclaredField("foo"); 
     field.setAccessible(true); 
     field.set(instance, "bar"); 
     // printing the field the "classic" way 
     System.out.println(instance.foo); // prints "bar" 
    } 

} 

请阅读this related post

+0

非常感谢你 – kevin

+0

@kevin不客气!如果我的回答适合您的需求,请不要忘记[接受它](http://meta.stackexchange.com/a/5235/186921)(与[您询问的其他问题]相同(http:// stackoverflow。 com/users/2299654/kevin?tab = questions):) – sp00m