Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring - creating objects with new operator using @Configurable & @Value annotations

Is it possible to use @Configurable on a class that's weaved using AspectJ and get Spring to load in values on fields/methods which are annotated with @Value?

I know its possible with @Autowired and @Resource etc... Are there any others.

e.g.

@Configurable
public Class MyObj{
 @Value("$(my.prop)")
 private String aField;

 public String getAField(){
   return aField;
 }
}

And then have something like

public aMethodSomewhereElse(){
   MyObj obj = new MyObj()
   assertNotNull(obj.getAField());
}

Are there any alternatives to being able to create MyObj with the new operator and still get spring to handle the annotations?

--EDIT:--

It IS possible to do this using new when using @Autowired, have a look at some Hibernate and JPA stuff with Spring and AOP... I've used this in the past to do some profiling of Java code. But I really want to use SPEL and @Value before I mock up a full example I was hoping to find the answer here. FYI - if you don't belive me the Spring Manual even says it is possible to do this, what I want to know is if its possible to use @Value annotations in the same scope...

The Spring container instantiates and configures beans defined in your application context. It is also possible to ask a bean factory to configure a pre-existing object given the name of a bean definition containing the configuration to be applied. The spring-aspects.jar contains an annotation-driven aspect that exploits this capability to allow dependency injection of any object.

And...

Using the annotation on its own does nothing of course. It is the AnnotationBeanConfigurerAspect in spring-aspects.jar that acts on the presence of the annotation. In essence the aspect says "after returning from the initialization of a new object of a type annotated with @Configurable, configure the newly created object using Spring in accordance with the properties of the annotation". In this context, initialization refers to newly instantiated objects (e.g., objects instantiated with the 'new' operator) as well as to Serializable objects that are undergoing deserialization (e.g., via readResolve()).

http://static.springsource.org/spring/docs/3.0.0.RC2/reference/html/ch07s08.html

Cheers.

like image 894
NightWolf Avatar asked Feb 27 '13 07:02

NightWolf


2 Answers

You are absolutely right - @Autowired fields will be wired in an @Configurable annotated class even outside of a Spring container, assuming that you have a AspectJ infrastructure in place.

You have noted a good catch though, @Value fields are processed by a Spring bean post processor(AutowiredAnnotationBeanPostProcessor), which resolves the @Value annotated fields. It does not act on objects instantiated outside of the container though - so in short, the @Autowired fields should get wired in, but @Value properties will not.

like image 131
Biju Kunjummen Avatar answered Sep 28 '22 00:09

Biju Kunjummen


Doing

MyObj obj = new MyObj()

means that obj is not managed by spring, so it will not do autowiring. Only way to do that is to obtain instance from an application context. For example:

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyObj obj = context.getBean("myBean");
like image 44
DominikM Avatar answered Sep 28 '22 01:09

DominikM