Sam Brannen opened SPR-8450 and commented
Autowiring a bean with an instance of itself is not something one would normally do, but there are cases where it might be useful -- for example, to route method calls _through_ the proxy that wraps the bean. There are of course alternatives to this, such as using load-time weaving with AspectJ proxies instead of JDK dynamic proxies.
Note that self-autowiring _by name_ via @Resource is permitted by the framework; whereas, self-autowiring _by type_ is not permitted by the framework as can be seen in the following code snippet from DefaultListableBeanFactory's findAutowireCandidates(String, Class, DependencyDescriptor) method.
for (String candidateName : candidateNames) {
if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, descriptor)) {
result.put(candidateName, getBean(candidateName));
}
}
The name of the bean (i.e., the bean that's trying to autowire itself) is beanName. That bean is in fact an autowire candidate, but the above if-condition returns false (since candidateName equals the beanName). Thus you simply cannot autowire a bean with itself _by type_ (at least not as of Spring 3.1 M2).
Add support for self-autowiring using @Autowired on fields and methods.
This topic was brought to our attention via a discussion on Stack Overflow.
Affects: 3.0.5
Issue Links:
@Autowired does not work for target bean of type Collection@Autowired self-injection in case of ambiguity18 votes, 23 watchers
Chris Beams commented
On review of the StackOverflow thread, I wonder whether the "workaround" approach of using @Autowired to inject the enclosing ApplicationContext and look the bean up isn't actually a better idea. It reveals the intention more clearly that the user wants the bean as managed by Spring, e.g. post-proxying, etc. It would probably never be intuitive for someone to see a FooService that uses @Autowired to inject a FooService into itself. The fact that @Resource works here is more an inadvertent bonus than it is a feature by design.
I understand that this approach complicates unit-testability somewhat, but the use cases for this (self-injection) are probably few and far between and thus a reasonable tradeoff.
Placing within the General Backlog where it can get voted up and receive further comments, but there is no immediate intention to resolve at this time.
Fred Clausen commented
This is a bonus to me. In my specific case, it means I don't have to mess with the default cache proxying:
@Service(value="fooService")
public JPAFooService implements FooService {
@Resource(name="fooService") FooService fooService; // only works if injected by name
@Cacheable
List<Foo> getAll() {
return dao.getFoos();
};
boolean hasFoo(Foo f) {
List<Foo> all = getAll(); // THIS WILL BYPASS THE CACHE
List<Foo> all2 = fooService.getAll(); // THIS WILL USE THE CACHE
}
}
Chris Beams commented
Hi Fred,
Your example helps make clear why this issue is probably best considered as an advertisement for AspectJ-based advice (as opposed to the proxy approach). By using load- or compile-time weaving and spring-aspect's built in AJ aspects, you can forget about this proxy business entirely.
The proxy approach hits about 80% of the use cases, and that's why we advocate it first. But cases like this are really where bytecode-weaving shines.
Ben Fagin commented
On the one hand, calling a method on a reference to your 'real' self could probably be described as an anti-pattern. On the other hand, any day that I can avoid bytecode weaving is a good day. The idea of using a self reference is certainly present in other languages. Used judiciously, perhaps in an application transitioning from proxying to weaving, autowiring a self reference can be helpful.
Is autowiring oneself by type safe though? Is there a risk of autowiring some other bean entirely?
Sam Brannen commented
Is autowiring oneself by type safe though?
No, it is potentially dangerous (see below).
Is there a risk of autowiring some other bean entirely?
Yes, autowiring by type could potentially result in a different bean of the same type being injected. That's why Fred Clausen, in his example above, explicitly references the bean by name in order to ensure that the bean gets a reference to itself (potentially proxied). He does this using the bean name/ID in conjunction with @Resource; however, the same could be achieved using qualifiers (i.e., via @Qualifier).
Niels Bech Nielsen commented
Given that the use case for this problem is self proxy invocation, wouldn't it be simpler to address the use case through an explicit annotation, (e.g @AutowireSelf, @AutowireProxy, or something). It would probably be easy for the BeanFactory to resolve the case correctly, and it would probably be more explanatory than both autowire-by-name and autowire-by-type.
I have found the use case a few times and keeps being amazed at how people work around the problem usually in some less than elegant way. Some by autowire of some kind or by massive delegation or using static holders. Usually the use case have been identified through a massive debugging effort, because the developer was unaware of the problem in the first place.
With a specific annotation it would be easy to document the effect in proxy annotations:
"Should you wish to call a method annotated with @xxxProxyAnnotationOfSomeKind from another method in the same class, you must use a self-proxy(link to annotation)."
Premraj Motling commented
@Juergen Will this be supported in coming version? I liked the idea of doing this explicitly (like having special annotation @AutowireSelf)
Juergen Hoeller commented
For 4.2, I intend to research the options and suggest a recommended solution for this scenario... A dedicated annotation may indeed be the best compromise.
Juergen
Eduardo Simioni commented
I have a use case affected by this problem, where I think the solution of having a specific annotation wouldn't work, or maybe it would, but then it would have to consider collections as well, holding self and others.
In my applications there is an event mechanism, to put it very simple:
All @ServiceS extend AbstractService, with the abstract having a:
@Autowired
private List\
The AbstractService triggers events on some common situations in my application.
A @Service can be EventListener, meaning that it can potentially be injected in itself through the eventListeners, since it extends AbstractService.
Now, naturally I'm not handling events from a service inside itself, but I need this to be implemented this way so that it is generic and duplication free.
The injection works normally, but there are some corner cases that I don't recall right now where it doesn't.
If you want more details or the exact corner cases, I could investigate and provide.
Ben Fagin commented
I have been using a @Self annotation in my own code to handle these situations. I usually find it necessary when I want to ensure that my declarative transaction and caching semantics are preserved. In a perfect world the weaving would take care of this, but I have never been able to get that to work 100% of the time.
This is the code I use in my own projects. While not the absolute best, it has worked so far.
@Component
public class SelfWiringBeanPostProcessor implements BeanPostProcessor, SmartLifecycle, BeanFactoryAware {
private final List<Callable<Void>> injections = new ArrayList<>();
private BeanFactory beanFactory;
private boolean isRunning = false;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
injections.add(() -> {
// find all fields marked @Self
ReflectionUtils.doWithFields(bean.getClass(),
// get the latest bean and inject it
field -> {
Object ref = beanFactory.getBean(beanName);
ReflectionUtils.makeAccessible(field);
field.set(bean, ref);
},
// filter by annotation
field -> field.isAnnotationPresent(Self.class)
);
return null;
});
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// ------------------------------------------------------------------- //
@Override
public boolean isAutoStartup() {
return true;
}
@Override
public void stop(Runnable callback) {
stop();
callback.run();
}
@Override
public void start() {
for (Callable<Void> method : injections) {
try {
method.call();
} catch (Exception ex) {
throw Throwables.propagate(ex);
}
}
isRunning = true;
}
@Override
public void stop() {
isRunning = false;
}
@Override
public boolean isRunning() {
return isRunning;
}
@Override
public int getPhase() {
return Integer.MIN_VALUE;
}
}
Othon Crelier commented
It will be really interesting to have this solved.
Particularly interested in @Async and @Transactional use cases.
Sam Brannen commented
FYI: this has been resolved in the following GitHub commit:
https://github.com/spring-projects/spring-framework/commit/4a0fa69ce469cae2e8c8a1a45f0b43f74a74481d
Peter Rader commented
Not working well in 4.3.5.RELEASE!
{{ /**
\
Not responsible in case of movements that are blessed in past (i.e. part of a
loading-process of mementos, deserialization, loading a.s.).
\
Notice that this council is only responsible for non-headless-environments.
*/
@Named
public final class LayerDropAuthorithy extends LayerDragNDropTransferHandler implements DropVetoCouncilor {
public LayerDropAuthorithy() {
System.out.println(SpringVersion.getVersion());
}
/**
* The council to decide where to drop elements.
*/
// @Inject
public final DropVetoCouncilor[] dropVetoCouncil = null;
@Inject
public final ApplicationContext ac = null;
@Override
public boolean allowsMove(final VectorPublishNode target, final Set<VectorPublishNode> nodesConcerned) {
boolean blocked = false;
for (DropVetoCouncilor dropVetoCouncilor : dropVetoCouncil) {
blocked |= dropVetoCouncilor.blockMove(nodesConcerned, target);
}
return blocked;
}
@Override
public boolean blockMove(Set<VectorPublishNode> nodesConcerned, VectorPublishNode target) {
// Block if root-element shall be moved.
for (VectorPublishNode vectorPublishNode : nodesConcerned) {
if (vectorPublishNode.getParent() == null) {
return true;
}
}
return false;
}
@PostConstruct
public void test() {
System.out.println(SpringVersion.getVersion());
System.out.println("dddddddddd->" + ac.getBeansOfType(DropVetoCouncilor.class).size());
}
}
}}
gives:
{{4.3.5.RELEASE
dddddddddd->1}}
but uncomment // @Inject gives {{
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'addSquare': Unsatisfied dependency expressed through field 'history'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'historyImpl': Unsatisfied dependency expressed through field 'layer'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'layerImpl': Unsatisfied dependency expressed through field 'dragNDropHandler'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'layerDropAuthorithy': Unsatisfied dependency expressed through field 'dropVetoCouncil'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'net.vectorpublish.desktop.vp.api.layer.dnd.DropVetoCouncilor[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'addSquare': Unsatisfied dependency expressed through field 'history'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'historyImpl': Unsatisfied dependency expressed through field 'layer'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'layerImpl': Unsatisfied dependency expressed through field 'dragNDropHandler'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'layerDropAuthorithy': Unsatisfied dependency expressed through field 'dropVetoCouncil'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'net.vectorpublish.desktop.vp.api.layer.dnd.DropVetoCouncilor[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1225)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:552)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.\
at net.vectorpublish.desktop.vp.VectorPublishApplicationContext.\
at net.vectorpublish.desktop.vp.Startup.main(Startup.java:31)
at VPTest.testMe(VPTest.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'historyImpl': Unsatisfied dependency expressed through field 'layer'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'layerImpl': Unsatisfied dependency expressed through field 'dragNDropHandler'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'layerDropAuthorithy': Unsatisfied dependency expressed through field 'dropVetoCouncil'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'net.vectorpublish.desktop.vp.api.layer.dnd.DropVetoCouncilor[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1225)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:552)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1136)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 46 more
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'layerImpl': Unsatisfied dependency expressed through field 'dragNDropHandler'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'layerDropAuthorithy': Unsatisfied dependency expressed through field 'dropVetoCouncil'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'net.vectorpublish.desktop.vp.api.layer.dnd.DropVetoCouncilor[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1225)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:552)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1136)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 59 more
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'layerDropAuthorithy': Unsatisfied dependency expressed through field 'dropVetoCouncil'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'net.vectorpublish.desktop.vp.api.layer.dnd.DropVetoCouncilor[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1225)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:552)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1136)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 72 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'net.vectorpublish.desktop.vp.api.layer.dnd.DropVetoCouncilor[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1474)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1102)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 85 more
}}
Peter Rader commented
Ignore last message please, using 4.3.4.RELEASE solved the problem. Looks like a different bug.
Most helpful comment
Othon Crelier commented
It will be really interesting to have this solved.
Particularly interested in
@Asyncand@Transactionaluse cases.