Spring @Autowired注解私有属性(无set方法)

今天看到一个POJO类中的某个私有属性通过@Autowired自动注入。

按照以前理解的依赖注入需要注入点,可以是set方法也可以是构造方法,但是此属性并没有可以通过外部access的方法,他是如何注入的呢?


在网上搜索了一番,答案如下:

stackoverflow.com/questions/4127365/how-can-spring-hibernate-access-private-members/4127403#4127403


You can set private a variable of another object through reflection. Here is an example on how to do it. Consider the following object with a private variable:

1
2
3
public  class  MyBean {
     private  String  message;
}

Normally the message field wouldn't be accessible from outside MyBean, however, SnoopyClass can set and get its value. I wrote two static methods: setValue which can set a value into a private field called fieldName of an Object bean and a getValue method which can get the value of a private variable called fieldName from an Object bean.

The main method just demonstrates its use by creating an Object of MyBean class, setting the message variable and retrieving it. I've actually tested this code as a standalone application and it works.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import  java.lang.reflect.Field;
public  class  SnoopyClass {
     private  static  void  setValue( Object  bean,  String  fieldName,  Object  value)
             throws IllegalArgumentException, IllegalAccessException,
             SecurityException, NoSuchFieldException {
         Field privateVar = bean.getClass().getDeclaredField(fieldName);
         privateVar.setAccessible( true );
         privateVar. set (bean, value);
     }
     private  static  Object  getValue( Object  bean,  String  fieldName)
             throws IllegalArgumentException, IllegalAccessException,
             SecurityException, NoSuchFieldException {
         Field privateVar = bean.getClass().getDeclaredField(fieldName);
         privateVar.setAccessible( true );
         return  privateVar. get (bean);
     }
     public  static  void  main( String [] argv)
             throws IllegalArgumentException, SecurityException,
             IllegalAccessException, NoSuchFieldException {
          MyBean instance =  new  MyBean();
          setValue(instance,  "message" "Shht! Don't tell anyone!" );
          System.out.println( "The message is '"  + getValue(instance,  "message" ));
     }
}

The implementation uses getDeclaredField method on the class of the Object, because this method can look for all fields, even private. In contrast, getField can only access public members. The next step is calling setAccessible on the field to allow reading and writing it. The last step, is simply use the get and set methods provided by the java.lang.reflect.Field class.

This kind of manipulation is allowed only if the security manager allows that. By default Java doesn't install any security manager, so in a standalone program that you launch through your IDE or the command line, you won't have any problems to use this technique. I've also tried, in a Spring Application under Tomcat, and it's still working.

The primary application, at least for me, is being able to set private variables in my unit tests, especially for Spring Beans, without polluting the interface with unneeded setters.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值