I seem to have come up with a problem.
I have a class
#Component
#Scope("prototype")
public class MyClass extends BaseClass {
....
...
#Async
public void doSomething() {
....
}
....
}
and a Spring Config that contains
<context:annotation-config />
<context:component-scan base-package="com.company.project" />
<task:annotation-driven executor="taskExecutor"/>
<task:executor id="taskExecutor" pool-size="10" queue-capacity="10" />
and in some part of the code i have
BaseClass bean = springBeans.getBean(MyClass.class);
but i am getting this exception
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'myClass' must be of type [com.company.project.MyClass], but was actually of type [$Proxy19]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:361)
I can understand its a proxy class, but not sure why Spring is not allowing the Proxy to be converted.
I have the cglib 2.2 no dep on the class path, along with the Spring 3.2 core libs.
can anyone point to any clues as to fixing this ?
In short, i want a method to be Async when called.
Since you have CGLIB, you might want to change the #Scope to
#Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
Related
I have a prototype Bean which is instantiated by singleton bean with a Provider:
#Component
#Scope("prototype")
class MyPrototype {}
#Component
class MySingleton {
#Autowired
javax.inject.Provider<MyPrototype> prototypeFactory;
}
This works fine, but our company rules state that #Autowired is not allowed; the common pattern is #Resource(SingletonBeanClass.BEAN_ID).
Is it possible to annotate the Provider this way so the Spring lookup can create it?
I'm aware I can add a factory method with #Lookup, or a singleton factory bean, but I prefer the Provider.
EDIT:
I didn't get it to work this way and in the end had to edit spring.xml; see below for details.
As you have an XML configuration file, you can configure it via XML in the following way:
<bean id="myPrototype" class="some.package.MyPrototype" scope="prototype" />
<bean id="mySingleton" class="some.package.MySingleton">
<lookup-method name="getPrototypeFactory" bean="myPrototype "/>
</bean>
In this way, you have to access to the myPrototype with the getPrototypeFactory() and not directly to the property. You can even remove the annotations on those 2 classes.
For any extra details, you can look at the following blog post Injecting a prototype bean into a singleton bean
For reference, if someone comes across this via Google:
I ended up needing to declare it in the spring.xml. I tried #Lookup, but even that didn't work due to the prototype-bean referencing yet another prototype-bean.
This is how it was recommended here,
but it does not work:
#Component("proto1")
#Scope("prototype")
class MyPrototypeBean1 {
#Lookup(value="proto2")
protected MyPrototypeBean2 createBean2() { return null; }
}
#Component("proto2")
#Scope("prototype")
class MyPrototypeBean2 {
}
#Component("singleton")
class MySingleton {
#Lookup(value="proto1")
protected MyPrototypeBean1 createBean1() { return null; }
}
This results in the error message "Cannot apply #Lookup to beans without corresponding bean definition" when trying to create "innerBean...".
I assume it is due to "lookup methods cannot get replaced on beans returned from factory methods where we can't dynamically provide a subclass for them" as is quoted in the link above.
So what I ended up doing in the spring.xml:
<bean name="proto2" class="my.package.PrototypeBean2" />
<bean name="proto1" class="my.package.PrototypeBean1" >
<lookup-method name="createBean2" bean="proto2" />
</bean>
<bean name="singleton" class="my.package.SingletonBean" >
<lookup-method name="createBean1" bean="proto1" />
</bean>
And this works.
For the unit tests, I had to subclass the respective classes:
class SingletonUnitTest {
#Mock
MyPrototypeBean1 bean1;
#InjectMocks
DummySingleton sut;
#Before public void setBean1() {
sut.bean = bean1;
}
static class DummySingletonBean extends MySingeton {
MyPrototypeBean1 bean;
protected MyPrototypeBean1 createBean1() {
return bean;
}
}
}
parent class is like this:
public class BaseDAO{
private DBRoute defaultDB;
public DBRoute getDefaultDB()
{
return this.defaultDB;
}
public void setDefaultDB(DBRoute defaultDB)
{
this.defaultDB = defaultDB;
}
}
I have create beans like below:
<bean id="adsConfigDB" class="net.flyingfat.common.dbroute.config.DBRoute">
<constructor-arg value="adsConfig" />
</bean>
<bean id="adsBizDateDB" class="net.flyingfat.common.dbroute.config.DBRoute">
<constructor-arg value="adsBizDate" />
</bean>
I want to inject superclass property defaultDB in subclass through byName, not byType, which is in subclass inject defaultDB using adsConfigDB or adsBizDateDB. Is there any way to do this with spring annotations? I already tried Autowired or Resource with constructor which doesn't work. By the way, I already know this can be done using XML.
#Qualifier annotation – This annotation is used to avoid conflicts in bean mapping and we need to provide the bean name that will be used for autowiring. This way we can avoid issues where multiple beans are defined for same type. This annotation usually works with the #Autowired annotation. For constructors with multiple arguments, we can use this annotation with the argument names in the method.
Your code will be like this..
#Autowired
#Qualifier("adsConfig")
private DBRoute defaultDB;
I have a configuration class which uses the #Configuration annotation and also extends the RepositoryRestMvcConfiguration.
as part of the extended class, there are overridable methods that allow configuration of the bean recipes. one of which is configuring the conversion services available to the spring component.
I would like to inject some beans into a list that is iterated over and added as a conversion service through this overrided method, My configuration java class is defined below:
#Configuration
#EnableJpaRepositories(basePackages = "com.example.model.repositories")
public class DataConfig extends RepositoryRestMvcConfiguration {
List<Converter<?,?>> converters;
//get
//set
#Override
protected void configureConversionService(ConfigurableConversionService conversionService){
for(Converter converter : converter){
conversionService.addConverter(converter);
}
}
}
The following defines my converters that i wish to inject in the app-context.xml file
<beans>
<bean id="fooToBarConverter" class="com.example.model.converters.FooToBarConverter" />
<bean id="barToFooConverter" class="com.example.model.converters.BarToFooConverter" />
<util:list id="myConverters" value-type="org.springframework.core.convert.converter.Converter">
<ref bean="barToFooConverter"/>
<ref bean="fooToBarConverter" />
</util:list>
</beans>
Is there a better way of providing these converters through spring configuration or do i need to explicitly list them as output of a function contained within my configuration class like:
#Bean
public List<Converter<?,?> myConverters(){
Arrays.asList(new FooToBarConverter(), new BarToFooConverter());
}
Your help is highly appreciated.
P.S. since you are so good at spring, would you mind having a look at my spring-data-rest-mvc related question? please and thank you.
By default, any #Autowired (or #Resource) annotated Collection (or List, Set, etc) of a certain type will contain all beans of that type discovered in the context. You could add an #Autowired in your setter and let Spring injects your controller for you.
If you need a more fine-grained control over which converters should be configured and which one should not, maybe you should configure the ConversionService altogether instead.
I need to wire external lib class to my bean,in order to use it as singleton.
.xml config:
<bean id="myBean" class="com.my.MyBean">
<property name="someLib" value="com.ExternalBean" />
</bean>
java bean:
#Service
public class MyBean {
#Autowired
private ExternalBean externalBean;
public void setExternalBean(ExternalBean externalBean) {
this.externalBean = externalBean;
}
Further I use wired variable externalBean in public method ,in order not to instantiate it in every method call.
Problem is it null.
Do I wire bean correctly?What is mistake.
You have to define the external class as a bean in order to make #Autowired work.
<bean id="externalBean" class="some.external.package.ExternalBean">
</bean>
<bean id="myBean" class="com.my.MyBean">
</bean>
Also, if you use #Autowired you don't need the setter for it.
loodakrawa is right. A second thing that can cause a problem is, that you have a xml bean declaration for myBean and additional annotated the bean with #Service. I guess this will cause trouble as soon as use enable component scan.
I think that the better ide ais to use context path scan:
<context:component-scan base-package="some.external.package">
</context:component-scan>
Make sure that all these classes are within the package. Then mark both classes with one of the Annotations (#Repository, #Service, #Component).
One of the benefits, no setter required.
P.S: If you re using scan base you don't need to declare class as bean, annotations are enough
Maybe, because of my wrong English, I couldn't understand the benefit of using #Autowired annotation.
According to the tutorial we can simplify the first(I.) case to second case(II.) by means of #Autowired.
My question is, what is the meaning of the #Autowired ? Because it doesnt tell any more, since without using #Autowired the compiler can figure out that "EmpDao emDao" and "EmpManager" are closely related according the declaration.
code cited from here
I.
<bean id="empDao" class="EmpDao" />
<bean id="empManager" class="EmpManager">
<property name="empDao" ref="empDao" />
</bean>
public class EmpManager {
private EmpDao empDao;
public EmpDao getEmpDao() {
return empDao;
}
public void setEmpDao(EmpDao empDao) {
this.empDao = empDao;
}
...
}
II.
<context:annotation-config />
<bean id="empManager" class="autowiredexample.EmpManager" />
<bean id="empDao" class="autowiredexample.EmpDao" />
import org.springframework.beans.factory.annotation.Autowired;
public class EmpManager {
#Autowired
private EmpDao empDao;
}
#Autowired is spring-specific. #Inject is the standard equivallent. It is an annotation that tells the context (spring, or in the case of #Inject - any DI framework) to try to set an object into that field.
The compiler has nothing to do with this - it is the DI framework (spring) that instantiates your objects at runtime, and then sets their dependencies at the points you have specified - either via XML or via an annotation.
I agree it is a possible scenario for a DI framework to try to inject dependencies into all fields, even if they are not annotated. (And if you want to exclude a particular field, to annotate it). But they chose the other strategy (configuration-over-convention). By the way:
if using xml config and choose some form of autowiring, the dependencies of the bean will be automatically autowired without the need to specify anything
you can specify per-context autowiring settings.
When the server bootstraps itself. It finds
<context:annotation-config />
in the application context and then goes through the classes defined in the contexts. If there are any beans that are autowired, it injects that into the class by referring the context file.
Basically, it promotes convention over configuration. That's what most frameworks do these days to reduce the development time.
the #Autowired Spring annotation tells Spring to for a bean named 'empDao' and inject it into the EmpManager class, without you having to add the empDao bean as a property in your spring config file.
#Autowired tells Spring to find a bean of the declared type and wire in that bean, rather than requiring an explicit lookup by bean name. It can, under certain circumstances, make configuring applications easier if you only have one implementation of your types in a given Spring context.