Spring beans understanding - java

What is the use of extends and parent attributes in spring bean file.
Is it related to a class extending another class. If some could share some thoughts around this it would be great. Some linke and examples would also be helpful.

The abstract and parent mechanism is used to keep your XML configuration DRY (Don't Repeat Yourself).
Consider you have 2 beans with 3 similar properties and 2 distinct.
Instead of repeating those 3 similar properties in both beans, you can do this:
make a bean that is abstract and holds those 3 common properties.
set the parent attribute on your 2 beans, to point to the abstract bean.
An example would be here.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="BaseCustomerMalaysia" class="com.mkyong.common.Customer" abstract="true">
<property name="country" value="Malaysia" />
</bean>
<bean id="CustomerBean" parent="BaseCustomerMalaysia">
<property name="action" value="buy" />
<property name="type" value="1" />
</bean>
</beans>

Related

OSGi Blueprint configuration: injecting a list of bean references

I am trying to inject a list of beans in a list property in my blueprint.xml (similar to what you would do in Spring configuration):
blueprint.xml:
<blueprint
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<bean id="myBean" class="MyClass" />
<bean id="anotherBean" class="AnotherClass">
<property name="myClasses">
<list>
<ref bean="myBean" />
<list>
</property>
</bean>
</blueprint>
AnotherClass:
public class AnotherClass {
private List<MyClass> myClasses;
public void setMyClasses(List<MyClass> classes) {
this.myClasses = classes;
}
}
I had a look at the Blueprint XML schema and the R4.2 enterprise spec (which we are using) and found nothing suitable. But this is just such an obvious use case that I can't believe that this is not possible.
Any suggestions what I am missing here and how to do this?
I came across same issue and found an answer here. In ref element, change from bean to component-id.
<bean id="myBean" class="MyClass" />
<bean id="anotherBean" class="AnotherClass">
<property name="myClasses">
<list>
<ref component-id="myBean" />
</list>
</property>
</bean>
The list element should actually work natively provided you are not suffering from a malformed xml problem as found in the example code (assuming a typo for the missing slash in the closing list tag).
Here is a very good slide deck with described usage:
http://www.slideshare.net/gnodet/osgi-blueprint-services-1622424
[original suggestion below may still work but should not be required]
However, you should still be able to use other spring schema.
Try adding the util schema:
xmlns:util="http://www.springframework.org/schema/util"
and then namespacing the list element:
<util:list>
<ref bean="myBean" />
</util:list>
(this works seamlessly in spring because the beans namespace imports several other namespaces, including "util", automatically)

How can i add a sub Tag to an Xml file already defined using Java?

I have an XML file that contains the configration of a Spring project and I want to dynamically add a new bean. I have to modify the initial xML file and add my new bean definition:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="config"
class="myclass">
<property name="configXml">
<value>config.xml</value>
</property>
</bean>
<-- here a want to add a new bean definition <bean>....</bean> -->
</beans>
Has anyone got an idea?
I'm still not 100% what you mean, but here's two cases to try.
If you want to specify properties of a bean based on some derived value you can use the Spring Expression Language
http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html
<bean id="someBean" class="example.SomeBean">
<property name="foo" value="#{config.whatever}"/>
</bean>
If you want to something more complex you can construct a bean programatically using a factory bean
<bean id="someBean" class="example.SomeBeanFactory">
<property name="config" ref="config"/>
</bean>
with something like
class SomeBeanFactory implements FactoryBean<SomeBean> {
public void setConfig(MyClass config) { ... }
public SomeBean getObject() {
...
}
}

Differences beetwen Beans configuration file and annotation use in Spring MVC?

I am studyng Spring MVC and I have find this simple Hello World tutorial: http://www.tutorialspoint.com/spring/spring_hello_world_example.htm
In this tutorial the author creat a Bean Configuration file named Beans.xml, something like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message" value="Hello World!"/>
</bean>
</beans>
Using tis file the Spring Framework can create all the beans defined and assign them a unique ID as defined in tag. And I can use tag to pass the values of different variables used at the time of object creation.
Is this the well know Bean Factory?
My doubt is related to the following thing: in my previous example I don't use a Bean Configuration file to define my bean, but I use the annotation to define what is a Spring bean and how this bean work (for example I use #Controller annotation to say Spring that a class act as a Controller Bean)
Use the bean configuration file and use the annotation have the same meaning?
Can I use both?
For example, if I have to configure JDBC can I configure it inside beans.xml file and at the same time can I use annotaions for my Controller class?
Tnx
Yes you can do that thing. Find a example below where controller has written with annotation and sessionFactory and data source has been created as xml bean which is wired into services -
<beans ...>
<!-- Controller & service base package -->
<context:component-scan base-package="com.test.employeemanagement.web" />
<context:component-scan base-package="com.test.employeemanagement.service"/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
...
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<!-- <value>com.vaannila.domain.User</value> -->
<value>com.test.employeemanagement.model.Employee</value>
...
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
...
</props>
</property>
</bean>
...
</beans>
Services Example where SessionFactory is injected.
#Repository
public class EmployeeDaoImpl implements EmployeeDao {
#Autowired
private SessionFactory sessionFactory;
}
I hope it helps you. :)
You can use both bean configuration through xml and through annotation. You can even define your controller in xml configuration files.
Using the #Controller annotation allows you to use component scanning to find your bean. A Controller is a simple stereotype bean (that's why you can simply declare it your xml files).
More details about usage/semantic of #Controller here

How to use a Spring config file in a Maven dependency

In dependency A I have the following:
<beans>
<bean
id="simplePersonBase"
class="com.paml.test.SimplePerson"
abstract="true">
<property
name="firstName"
value="Joe" />
<property
name="lastName"
value="Smith" />
</bean>
</beans>
And then in project B, I add A as a dependency and have the following config:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean
id="simplePersonAddress01"
parent="simplePersonBase">
<property
name="firstName"
value="BillyBob" />
<property
name="address"
value="1060 W. Addison St" />
<property
name="city"
value="Chicago" />
<property
name="state"
value="IL" />
<property
name="zip"
value="60613" />
</bean>
</beans>
When I use ClassPathXmlApplicationContext like so:
BeanFactory beanFactory = new ClassPathXmlApplicationContext( new String[] {
"./*.xml" } );
SimplePerson person = (SimplePerson)beanFactory.getBean( "simplePersonAddress01" );
System.out.println( person.getFirstName() );
Spring complains as it can not resolve the parent xml.
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'simplePersonBase' is defined
I am sure there is a way to do this, however, I have not found it. Does anyone know how?
Try with the classpath*: prefix.
Does A.jave have the corresponding xml file? In project A, did you the xml inside src/main/resources?
Not really an answer to the question - but beware of this approach.
It can be a nightmare resolve errors. Imagine getting an spring error on startup - the only way to resolve it is cracking open all the jars to find any application contexts held within.
At the very least put the application context files in a distinct package and specify any you wish to use by name.
A *.xml from the root of the classpath is a recipe for disaster.

Declaring an explict object dependency in Spring

The basic problem I have here is that I have one xml file that is being used as a utility file and imported into other xml files. It defines a series of objects for connecting to a platform and providing an interface to it. The beans in this file are defined to be lazy-initialised so that if you do not want to connect to the platform you will not but if you start referencing the appropriate bean then everything should get up and running.
The basic problem I have is that one of the beans in this set is not explicity referenced by any of the others but it is required to be constructed as it will call a method on one of the other beans in order to "activate" it. (It is acting as a gate keeper by switching on/off the connectivity based on what it detects as the state of the platform).
Here's a dummy of the sort of XML setup I have:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd"
default-lazy-init="true">
<!-- Provides the connection to the platform -->
<bean id="PlatformConnection">
<constructor-arg ref="PlatformConnectionProperties" />
</bean>
<!-- This bean would be overriden in file importing this XML -->
<bean id="PlatformConnectionProperties"/>
<!-- Controls the databus to be on/off by listening to status on the Platform
(disconnections/reconnections etc...) -->
<bean lazy-init="false" class="PlatformStatusNotifier">
<constructor-arg ref="PlatformConnection" />
<constructor-arg ref="PlatformConnectionDataBus" />
</bean>
<!-- A non platform specific databus for client code to drop objects into -
this is the thing that client XML would reference in order to send objects out -->
<bean id="PlatformConnectionDataBus" class="DataBus"/>
<!-- Connects the DataBus to the Platform using the specific adaptor to manage the java object conversion -->
<bean lazy-init="false" class="DataBusConnector">
<constructor-arg>
<bean class="PlatformSpecificDataBusObjectSender">
<constructor-arg ref="PlatformConnection" />
</bean>
</constructor-arg>
<constructor-arg ref="PlatformConnectionDataBus" />
</bean>
</beans>
Now basically I want to remove the lazy-inits here that are required to get this thing to work properly. The objects referenced by the client XML are the PlatformConnection and the PlatformConnectionDataBus. How can I explicity declare that I want those other beans constructed if they are referenced?
You can add an explicit dependency from one bean to another by using the depends-on attribute:
<bean id="a" class="A"/>
<bean id="b" class="B" depends-on="a"/>
If I'm understanding your questin correctly, then I suggest you make all of your bean definitions lazy-init="true", and use depends-on to tie them together, for example:
<bean id="PlatformStatusNotifier" lazy-init="false" class="PlatformStatusNotifier">
<constructor-arg ref="PlatformConnection" />
<constructor-arg ref="PlatformConnectionDataBus" />
</bean>
<bean id="PlatformConnectionDataBus" lazy-init="false" class="DataBus" depends-on="PlatformStatusNotifier"/>
So if your client config were to express a dependency on PlatformConnectionDataBus, then that would trigger the initialisation of PlatformConnectionDataBus, which in turn would trigger the initialisation of PlatformStatusNotifier.

Categories