2013年11月18日星期一

Ask : Spring @ Autowired annotation implements an interface member variables failed

Scene :
1, class A, class member variables in B, Class B uses @ Autowired annotation injected A of the way .
2, class B implements the interface IB.

question :
startup error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a':
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: com.siqisoft.test.B com.siqisoft.test.Ab;
nested exception is java.lang.IllegalArgumentException:
Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $ Proxy23

questions :
Why implements an interface B can not be injected into A do ?

Class A:

package com.siqisoft.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class A {
@Autowired
B b;
}


Class B:

package com.siqisoft.test;

import org.springframework.stereotype.Component;

@Component
public class B {
 public  void  BMethod(){};
}

B interface implemented

package com.siqisoft.test;

public abstract interface IB   {

}


------ Solution ------------------------------------- -------
< br> ------ Solution ----------------------------------------- ---

Caused by: java.lang.IllegalArgumentException: Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $ Proxy23
no set method
------ Solution -------------------------------- ------------
Error creating bean with name 'a':

and whence a row ?

thinking about you , the answer is as follows:
use
@ Autowired
@ Qualifier ("b") / / with the B type to inject Please note that the first letter lowercase class name
private BI b

------ For reference only ---------------------------------- -----
try
1, when B does not write any method, started successfully.
2, when B does not inherit IB , start successfully .

------ For reference only ---------------------------------- -----
entire error stack

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.siqisoft.test.B com.siqisoft.test.A.b; nested exception is java.lang.IllegalArgumentException: Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $Proxy23
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4135)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4630)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:445)
at org.apache.catalina.core.StandardService.start(StandardService.java:519)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:581)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.siqisoft.test.B com.siqisoft.test.A.b; nested exception is java.lang.IllegalArgumentException: Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $Proxy23
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
... 28 more
Caused by: java.lang.IllegalArgumentException: Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $Proxy23
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:498)
... 30 more

------ For reference only ----------------------------------- ----
seemingly @ autowired interface is injected into it.

you put B b; into IB b try

------ For reference only ---------------------------------- -----
  This reply was moderator deleted at 2011-07-21 11:29:59

------ For reference only ---------------------------------- -----
try
The B b; into IB b try
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'a':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: com.siqisoft.test.IB com.siqisoft.test.Ab;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type [com.siqisoft.test.IB] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@ org.springframework.beans.factory.annotation.Autowired (required = true)}

thinking
this approach as reported above error .
Consider this: If the entire project has multiple class implements the IB interface , then A would like to use IB How do I decide what it ? IB should be written so that it is wrong .
And IB has no method to call me , I want to call the B class method . Just very unfortunate , B must be to achieve IB.

original model
fact, is to achieve a Class B ApplicationListener interface to respond to events in a class. Class B is set in a List member variable cache all events , I sometimes need to request this Class A Class B to get a list of events that have occurred , so wanted to Class B Autowired into the A class.
------ For reference only -------------------------------------- -


verification

added a Set method , it remains difficult to use .

thinking
In fact , in a timely manner no set method private fields , Spring still has many means of setting the value to it , this is not the cause of the problem
------ For reference only ------- --------------------------------


@ Autowired is no set method
------ For reference only --------------------- ------------------


explanation
my A comment on the : @ Component. Let Spring starts, scans that this is a component, and then automatically instantiate it , instantiate a time and found that it has a member variable b to inject , went busy looking for b, find b when a problem arises . . . .

try
I used your method , A class member variables to IB interface , and then annotated with @ Qualifier ("b"), successfully started.

I moved to a formal code try.


------ For reference only ---------------------------------- -----
solve the problem just fine . I remember closing
------ For reference only ------------------------------------ ---
Oops ! Or not, because IB does not want me in the A class method called BMethod. . . .
------ For reference only -------------------------------------- -
Interface Why do you want to define as abstract ~
------ For reference only ------------------------- --------------


Then you do not let B Actual IB interface . . Directly with the B to inject .

Or, you add an IB interface BMethod.
------ For reference only -------------------------------------- -


interface itself is the highest level of abstraction , so with no abstract in grammar are possible
------ For reference only -------------- -------------------------
landlord not solve the problem ?
------ For reference only -------------------------------------- -

guess
@ Autowired and @ Qualifier with the use of the time, still too @ Autowired first hurdle , in the bean pool must find the corresponding Type of the bean, and then carried out under the @ Qualifier name match.
The B class which implements IB interface , in the Spring bean pool , it was considered only type IB , are not considered to be B type.
So , @ Autowired and @ Qualifier can not solve this problem.

solutions
instead of using the @ Resource annotation @ Autowired, @ Resource is based entirely on the names match .

end
ultimately did not solve the practical problems encountered in the development , since Class A in the actual development environment when a Tag, managed to Spring , as it were Tomcat quit, parsing jsp when he can not find in the context A this label. The ultimate solution is , B still achieve IB interface , an increase in B for A static method call .

------ For reference only ---------------------------------- -----
I do not know your specific development environment is how .

@ Autowired is self- inject it right , you write an interface , he will automatically look for him to achieve, if there are multiple realized he was dependent on the @ Qualifier
@ Resource is specified directly Mingzi , of course .
------ For reference only -------------------------------------- -
need to add in the xml under bean
------ For reference only ---------------------------- -----------
there is no profile information posted out , I suspect the problem is the configuration file
------ For reference only ------ ---------------------------------

in fact, the great god was right there your profile may be a problem , and I is injected directly into the interface is ok, but ! ! ! ! But ! ! ! I separate the examples necessarily be springMVC did not succeed ! ! That depressed. . .
------ For reference only -------------------------------------- -
try to call in your action of all the injection interface class inside with @ component try
------ For reference only ------------ ---------------------------
interface class before the class definition plus @ Service

没有评论:

发表评论