问题
How can I get an already existing object spring managed? I would like to hook it up to Springs AoP
capabilities using aspectj
. I know this to be a challenge since Spring AoP
uses dynamic proxies which probably are created along with the object.
Why do I need this?
I have a third-party class which takes a constructor argument which is only known in runtime,
hence it seems I cannot add it to my applicationContext
or use springs FactoryBean
interface for construction. Is there any other way?
I've already tried the following without great success:
Obj obj = new ThirdPartyObj("runtime constructor arg");
appContext.getAutowireCapableBeanFactory().initializeBean(obj, "Obj");
It might be spring-managed, but I still cannot use it to trigger aspects.
[EDIT] axtavt pointed out the problem is that I don't use the object returned from initializeBean(..)
. Both mentioned approaches work, but only if:
Using interface
ObjInterface obj = (ObjInterface) ac.getBean("obj", args);
or we will get a:java.lang.ClassCastException: $Proxy28 cannot be cast to com.company.Obj
Not using interface but enable
CGLIB
. This requires a non-private default constructor, or we will get a:java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
回答1:
You should be able to trigger aspects using this (note that you need to use returned object which can be a proxy):
Obj obj = new ThirdPartyObj("runtime constructor arg");
obj = appContext.getAutowireCapableBeanFactory().initializeBean(obj, "Obj");
Another option is to declare it as a regular bean and pass the constructor argument via getBean()
:
Obj obj = appContext.getBean("Obj", "runtime constructor arg");
回答2:
Why not create a new class that wraps the functionality of ThirdPartyObj
, and make that Spring-managed. Dependencies can then be injected into its fields and method parameters, and passed on the the instantiated ThirdPartyObj
.
回答3:
How about annotating the domain object with @Configurable annotation? I myself haven't tried it but seems like it might helpful in your scenario. AspectJ and Spring would create a managed object with attributes defined in the bean. The then created object instance can be used.
来源:https://stackoverflow.com/questions/5288640/make-object-spring-managed