How would I specify an anonymous inner bean in a named Spring Service?
#Service("myNamedService")
public class myNamedServiceClass {
private InnerBeanType innerBean;
#Autowired
public void setInnerBean(InnerBeanType innerBean) {
this.innerBean = innerBean;
}
}
I'm basically trying to achieve the equivalent of the following Spring XML wiring:
<bean name="myNamedService" class="somePackage.myNamedServiceClass">
<property name="innerBean">
<bean class="somePackage.InnerBeanType"/>
</property>
</bean>
Equivalent using pure annotations is I think not possible. You can use #Configuration though if the purpose is to not expose innerBean as a visible bean this way:
#Bean
public MyNamedServiceBean myNamedServiceBean(){
MyNamedServiceClass myNamedServiceBean = new MyNamedServiceClass();
myNamedServiceBean.setInnerBean(new InnerBeanType());
return myNamedServiceBean;
}
Related
This may looks like a duplicate of this question. But this is different.
I was trying to refactor my legacy code by using method injection in spring.
I have a bean class which contains many static helper methods. My targeted method as follows:
Context.java
private static MessageSender messageSender;
//...
public static MessageSender getMessageSender(){
return messageSender;
}
Context bean
<bean id="context" class="org.abc.Context">
<property name="messageSender"><ref bean="mailMessageSender"/></property>
</bean>
MailMessageSender.java
public abstract class MailMessageSender{
protected abstract Session createSession();
//using createSession() somewhere in this class
}
MailMessageSender bean
<bean id="session" class="javax.mail.Session" scope="prototype" />
<bean id="mailMessageSender" class="org.abc.MailMessageSender">
<lookup-method name="createSession" bean="session"/>
</bean>
I'm getting invalid property error when I'm installing the project.
You can't inject static field, change your variable in Context.java become like this:
private MessageSender messageSender;
//...
public MessageSender getMessageSender(){
return messageSender;
}
I am working on this Spring MVC project where I have trouble getting this Dao class auto wired in the controller through an Interface that is implemented by the Dao. This is portion of my spring-config.xml. I am using aspectJ, Annotation and TX management.
<aop:aspectj-autoproxy />
<context:component-scan base-package="com.simulator" />
<context:annotation-config />
<tx:annotation-driven />
<context:property-placeholder
location="classpath*:config.properties" />
<bean id="oidDao" class="com.simulator.service.OidDao">
<property name="ipaddressNC" value="${ipaddressNC}" />
<property name="ipaddressOM" value="${ipaddressOM}" />
</bean>
Dao class:
#Component
public class OidDao implements OidManager {
#Autowired
private SessionFactory sessionFactory;
private String ipaddressNC;
private String ipaddressOM;
public String getIpaddressNC() {
return this.ipaddressNC;
}
public void setIpaddressNC(String ipaddressNC) {
this.ipaddressNC = ipaddressNC;
}
public String getIpaddressOM() {
return ipaddressOM;
}
public void setIpaddressOM(String ipaddressOM) {
this.ipaddressOM = ipaddressOM;
}
OidManager:
public interface OidManager {
public String getIpaddressNC();
public String getIpaddressOM();
}
Controller:
#Controller
public class HomeController {
#Autowired
OidManager oim;
#RequestMapping(value = "/", method = RequestMethod.GET)
public String indexpage(ModelMap modelMap) {
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"spring-config.xml"});
o = (OidManager)context.getBean("oidDao");
o.getIpaddressNC(); // ---> this returns data read from ext properties file and works fine
oim.getIpaddressNC(); // ---> this returns null`
I am trying to re-use the Dao, hence I dont want to call the ApplicationContext multiple times from each method. What am I doing wrong? If I make the variables getIpaddressNC, getIpaddressOM static, then auto wiring works, if not oim returns null though the variables are initialized via setters on application load.
You used both Component Scanning and Manual Wiring for OidDao. You defined oidDao in xml config, as follows:
<bean id="oidDao" class="com.simulator.service.OidDao">
<property name="ipaddressNC" value="${ipaddressNC}" />
<property name="ipaddressOM" value="${ipaddressOM}" />
</bean>
Then, added a Component annotation on OidDao, as follows:
#Component
public class OidDao implements OidManager {
...
}
Drop the Component annotation and you'll be fine, i guess! Because otherwise, <context:component-scan base-package="com.simulator" /> will pick OidDao and instantiate an instance from it with default constructor and without calling your setters.
You are using #Component annotation + you have also defined a bean. Therefore actually two beans are created. One created due to use of #Component would have the properties set to 'null'. This is expected since you are not setting the properties to any value. Either remove #Component annotation and use 'autowire-candidate="true"' property on bean definition or else remove the bean definition in XML and use relevant annotation on the class to set properties to correct values from property file.
Change your bean definition to:
<bean id="oim" class="com.simulator.service.OidDao">
<property name="ipaddressNC" value="${ipaddressNC}" />
<property name="ipaddressOM" value="${ipaddressOM}" />
</bean>
Let this create bean with id oim which can be set to the property oim in your Controller.
I currently have the following Spring bean definitions:
<bean id="myAwesomeBeanSetup" class="com.beanpckg.SuperBean" scope="singleton" init-method="doPreStep"/>
<bean id="myAwesomeBean" class="com.beanpckg.SuperBean" scope="prototype" depends-on="myAwesomeBeanSetup"/>
Essentially, what I need is to run SuperBean.doPreStep only once, but still have a fresh instance of SuperBean for subsequent calls. Since I have a lot of beans with such structure, I was wondering, is there a more elegant way to achieve this without having two lines of definitions? Note that there could also be "cross-bean" dependencies, for example:
<bean id="myAwesomeBeanSetup" class="com.beanpckg.SuperBean" scope="singleton" init-method="doPreStep"/>
<bean id="myAwesomeBean2Setup" class="com.beanpckg.SuperBean2" scope="singleton" init-method="doPreStep"/>
<bean id="myAwesomeBean" class="com.beanpckg.SuperBean" scope="prototype" depends-on="myAwesomeBeanSetup,myAwesomeBean2Setup"/>
You can put your code in the static initialization block as following:
public class SuperBean {
// …
static {
doPreStep();
}
public static void doPreStep() {
}
}
Alternatively, if you want a pure Spring solution, you can implement a FactoryBean and invoke the doPreStep() in its init method as following:
public class SuperFactoryBean implements FactoryBean<SuperBean>{
public void init() {
SuperBean.doPreStep();
}
public boolean isSingleton() {
return false;
}
public SuperBean getObject(){
return new SuperBean();
}
public Class<SuperBean> getObjectType() {
return SuperBean.class ;
}
}
And define your bean as following:
<bean id="myAwesomeBean" class="com.beanpckg.SuperFactoryBean" init-method="init">
</bean>
Depending what you want to achieve within your awesome superclass:
For me this would be the perfect usecase of having a separate singleton with the common code and autowire it into your prototype.
Since your init will not be different per bean why having it in a superclass?
How can I get Spring to instantiate a bean that does not have a no-argument constructor? I'm using java-config (not xml-config). It seems to work using XML -but shouldn't I be able to do the same thing with annotations somehow?
Straight from the tutorial, the following example is the equivalent in xml-config:
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg index="0" value="7500000"/>
<constructor-arg index="1" value="42"/>
</bean>
It also mentions the use of #ConstructorProperties annotation, which I've tried to use -but I can't get it to work. I keep getting a BeanInstantiationException.
#Configuration
public class MyConfiguration {
#Bean
public ExampleBean exampleBean() {
return new ExampleBean(7500000, 42);
}
}
Or:
#Configuration
#PropertySource(value = { "my.properties" })
public class MyConfiguration {
#Value("{prop.value1}")
private int value1;
#Value("{prop.value2}")
private int value2;
#Bean
public ExampleBean exampleBean() {
return new ExampleBean(value1, value2);
}
}
also from the link below
http://docs.oracle.com/javase/6/docs/api/java/beans/ConstructorProperties.html
what i understood is, #ConstructorProperties annotation is not to be used as a replacement for your xml-config.
Can you use #Autowired with #Qualifier, like in another SO Article?
You can use #Autowired or #Inject
I have the following abstract class, with a property called portletBaseViewName which is meant to be different for every concrete Controller extending AbstractController.
public abstract class AbstractController {
private String portletBaseViewName;
protected String getPortletBaseViewName() {
return portletBaseViewName;
}
#Required
#Value("")
public void setPortletBaseViewName(String portletBaseViewName) {
this.portletBaseViewName = portletBaseViewName;
}
}
#Controller
#RequestMapping("VIEW")
public class ReservationOfBooksViewController extends AbstractController{}
I know that is possible declaring the injections in a XML, doing so:
<bean id="abstractController" class="es.alcampo.portalweb.portlets.common.controller.AbstractController" abstract="true">
<property name="portletBaseViewName" value="" />
</bean>
<bean id="reservationOfBooksViewController" class="es.example.portalweb.portlets.reservationofbooks.controller.ReservationOfBooksViewController" parent="abstractController">
<property name="portletBaseViewName" value="reservationOfBooks" />
</bean>
<bean id="myShopViewController" class="es.example.portalweb.portlets.reservationofbooks.controller.MyShopViewController" parent="abstractController">
<property name="portletBaseViewName" value="myShop" />
</bean>
Do I need to redefine?:
#Controller
#RequestMapping("VIEW")
public class ReservationOfBooksViewController extends AbstractController{
#Value("reservationOfBooks")
public void setPortletBaseViewName(String portletBaseViewName) {
super.setPortletBaseViewName(portletBaseViewName);
}
}
I don't like the previous option, which would be the most elegant option if there is to reach the purpose of injecting one value or another depending on the concrete class through annotations?
I know inheritance and annotations sometimes conflict.
Thanks a lot.
Do you actually need #Value here?
#Value is useful when it contains some expressions evaluated by Spring at runtime. Otherwise you can replace it with explicit initialization (and keeping the setter method allows you to override this values from XML configuration):
public abstract class AbstractController {
protected String portletBaseViewName = "";
public void setPortletBaseViewName(String portletBaseViewName) {
this.portletBaseViewName = portletBaseViewName;
}
}
#Controller
#RequestMapping("VIEW")
public class ReservationOfBooksViewController extends AbstractController{
public ReservationOfBooksViewController() {
this.portletBaseViewName = "reservationOfBooks";
}
}
As shown by #axtavt in previous answer, you don't need any annotation in AbstractController. In addition, you don't need to define abstractController in XML. In case, you want to configure common properties in all of its subclasses, you can put them in abstract bean (without any class name):
<!-- define common properties in abstract bean-->
<bean id="controllerTemplate" abstract="true" />
<bean id="reservationOfBooksViewController" class="es.example.portalweb.portlets.reservationofbooks.controller.ReservationOfBooksViewController" parent="controllerTemplate">
<property name="portletBaseViewName" value="reservationOfBooks" />
In subclasses, #Value annotation is not required and you can use 'getPortletBaseViewName()' method to get view name.