1

today,i learned that we could use spring's @AutoWired annotation to complete auto-injection, @AutoWired could be used in many conditions ,like

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

but we can also put the @AutoWired on a private field,like this

@AutoWired
private Instrument instrument;

i was wondering ,how could spring inject an object into a private field,i know we could use reflection of java to get some meta data,when i use reflection to set a object on a private field ,here comes a problem ,following is the stacktrace

 java.lang.IllegalAccessException: Class com.wire.with.annotation.Main can not access a member of class com.wire.with.annotation.Performer with modifiers "private"

some body can explain it ? why spring could inject an object into a private field with no setter method . thanks a lot

kevin
  • 43
  • 1
  • 8

2 Answers2

7

This is done using reflection you need to Filed.setAccessible(true) to access the private fields.

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

update:-

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 Security manager(if enable) also prevents Spring from accessing private fields

vikrant singh
  • 2,091
  • 1
  • 12
  • 16
3

I guess you forgot to set setAccessible(true) on the field you're trying to access:

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

}

Please read this related post too.

Community
  • 1
  • 1
sp00m
  • 47,968
  • 31
  • 142
  • 252
  • @kevin You're welcome! If my answer suited your needs, don't forget to [accept it](http://meta.stackexchange.com/a/5235/186921) (same for [the other questions you asked](http://stackoverflow.com/users/2299654/kevin?tab=questions) :) – sp00m Jul 16 '13 at 12:56