2013-07-16 68 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