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
Related
I have the project structure as following -
Facade -> Service-> DAO
In the DAO layer, when the beans are initialized then many dependencies are injected from a property file. Therefore, the properties file must be read first and then the remaining dao beans must be created. When the application is started then it gives an error that Spring cannot resolve a placeholder.
The DAO-application-context.xml is like-
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="prop">
<value>app.properties</value>
</property>
</bean>
<import resource = "a-dao.xml" />
<import resource = "b-dao.xml" />
<import resource = "c-dao.xml" />
Now in all the child application contexts i.e. a-dao, etc, we have-
<bean ....>
<property name = "xyz">
<value>${appValue}<value/>
</property>
<bean>
The error received is that appValue cannot be resolved. I think that it may be due to incorrect sequence of bean creation. However, the same config is working in another larger project.
I have checked Order of Spring Bean Initialization but implementing that solution would not be feasible. Is there any other way ?
Reg this Block of Configuration, property prop seems to be wrong
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="prop">
<value>app.properties</value>
</property>
</bean>
According to the Spring documentation
You could use the property location or locations to set the one or multiple values of the properties file.
So the code should be refactored to
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>app.properties</value>
</property>
</bean>
I'm currently getting started on a project that uses spring-data in combination with JPA/Hibernate.
Right now, I'm injecting JpaRepositories using #Autowired annotations on the properties in question, e.g.:
#Component
public class EmployeeGenerator implements IDataGenerator {
...
#Autowired
private IEmployeeDao dao;
...
}
.. where IEmployeeDao is an interface extending JpaRepository that is annotated as #Repository:
#Repository
public interface IEmployeeDao extends JpaRepository<Employee, Integer> {
/**
* Finds employees by username.
*
* #param username the username
* #return the list of employees
*/
List<Employee> findByUsername(String username);
Everything works fine using this approach - However, I'm rather used to doing most of my spring configuration work in XML because I personally like the idea of all relevant confguration being in the same place and visible at the first glance.
Now, as far as I understand JPA and spring-data, the repository instances are somehow created by the JPA entity manager, so I should be able to specify them as beans in the spring config xml using.. some kind of factory method?
I guess I'm looking for something along the lines of:
<import resource="classpath:spring/db-context.xml"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="..."/>
<property name="dataSource" ref="..."/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
</props>
</property>
</bean>
...
<bean id="employeeDaoImpl" class="IEmployeeDao">
<factory-method="?????"> <!-- Is something like this possible??? -->
</bean>
After some reading I guess that autowiring the repositories is the "recommended" approach, and I do see some benefits doing it like that,
but still, out of interest, I'd like to get it working with pure-xml configuration (or at least without #Autowired, that is)
You can declare the repositories using <jpa:repositories />. Then you can use the repository references in your XML configuration.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<repositories base-package="com.acme.repositories" />
</beans:beans>
In this case we instruct Spring to scan com.acme.repositories and all its sub packages for interfaces extending Repository or one of its sub-interfaces. For each interface found it will register the persistence technology specific FactoryBean to create the according proxies that handle invocations of the query methods. Each of these beans will be registered under a bean name that is derived from the interface name, so an interface of UserRepository would be registered under userRepository. The base-package attribute allows the use of wildcards, so that you can have a pattern of scanned packages.
You can read more about it in the docs: http://docs.spring.io/spring-data/jpa/docs/1.3.0.RELEASE/reference/html/repositories.html#repositories.create-instances
I can't get #Transactional annotation to work with xml-defined bean. I don't know if xml definition has anything to do with it. Maybe it's the issue with OSGi.
<bean id="myDao"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="txManager"/>
<property name="target" ref="myDao_t"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_MANDATORY,
timeout_60,
-Exception
</prop>
</props>
</property>
</bean>
When I specify a proxy with xml like above it works.
I have <tx:annotation-driven transaction-manager="txManager" /> specified in the same bundle-context.xml where the bean definition is.
MyDao is just a simple class implementing interface with one method.
There is no exception, it just doesn't create proxy for myDao.
What might be missing?
<bean id="myPlanner" class="com.something.planner.MyPlanner">
<property name="myDao" ref="myDao" />
</bean>
Try this:
The class of the bean myDao should be MyDao (the type of the DAO instead of TransactionProxyFactoryBean).
Put the annotation #Transactional on each public method in MyDao.java.
Spring should then automatically create a proxy for you. The approach in your question looks like "I try to create and configure the proxy factory myself".
While there surely is away to do that, I don't know exactly how you would do that. Instead, I rely on <tx:annotation-driven> and the #Transactional annotation.
EDIT You're using Spring 2.5.6A.
I just checked and #Transactional was added with Spring 1.2. But I'm not sure when <tx:annotation-driven> was added. The related EnableTransactionManagement was added with 3.1.
But the XML element is in this schema: http://www.springframework.org/schema/tx/spring-tx-2.5.xsd so it should be available in 2.5.
Maybe you're missing the necessary AOP libraries (cglib) on the classpath?
I am playing around with a Spring MVC + Hibernate + MySQL "Hello World" app, and am currently trying run the following integration test on a Spring MVC controller using jUnit.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({"file:src/main/webapp/WEB-INF/springapp-servlet.xml"})
public class InventoryControllerIT
{
#Autowired
private InventoryController controller;
#Test
public void handleRequest_anyRequest_returnsSuccessfully() throws Exception
{
ModelAndView modelAndView = this.controller.handleRequest(null, null);
}
}
However, every time I do so I get the following exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [springapp.web.InventoryController] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Previously I hadn't implemented any real data access and the test passed fine, but now that I have added a Hibernate implementation of my DAO along with spring transaction management I get this error. Here are the relevant parts of my applet context configuration xml:
<?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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean name="/hello.htm" class="springapp.web.InventoryController">
<property name="productManager" ref="productManager" />
<property name="productDao" ref="productDao" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
...
<!-- Hibernate -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingJarLocations">
<list>
<value>WEB-INF/lib/springapp-dataaccess*.jar</value>
</list>
</property>
</bean>
<bean id="productDao" class="springapp.dataaccess.dao.ProductHibernateDao">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
</beans>
If I remove the <tx:annotation-driven /> from the config then the above exception does not occur, but then the test fails because the data access call that occurs in the handler no longer has an open transaction. The app runs just fine outside of the test. Anyone have any ideas as to what the issue is?
When InventoryController implements any interfaces Spring by default applies transactional aspect to it using interface-based proxy. Such a proxy implements interfaces of InventoryController, but it's not a subclass of InventoryController, therefore it cannot be injected into a field of type InventoryController.
You either need to use interface as a type of the field to be autowired, or configure Spring to apply target-class-based proxy instead.
See also:
7.6 Proxying mechanisms
I had a similar issues while running the unit tests of a small library I was building.
replace your :
<tx:annotation-driven />
with
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
Note that on my project I also had to add the following dependency (maven project) for the unit tests:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
<scope>test</scope>
</dependency>
Best regards.
I have a JSF 2.0 application and I am integrating Spring so I can make use of the hibernateTemplate. I already consulted the Spring documentation on JSF integration and have taken steps to set it up. All of my bean classes extend an abstract super class called SuperBean. SuperBean is the desired point of injection, saving me from having to declare all of my beans in Spring. I was hoping to just declare it as abstract="true" and any subclass bean extending the SuperBean class would have the dao injected. At runtime it is null.
<bean id="serviceTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="*"/>
</props>
</property>
</bean>
<bean id="daoServiceTarget" class="com.example.service.DaoService">
<property name="mainDAO" ref="mainDAO"/>
</bean>
<bean id="daoService" parent="serviceTemplate">
<property name="target" ref="daoServiceTarget"/>
</bean>
<bean id="superBean" class="com.example.beans.SuperBean" abstract="true">
<property name="daoService" ref="daoService"/>
</bean>
Am I able to simply declare this superclass SuperBean and expect Spring to inject the dao? I don't want to have to declare every bean class in spring.
I suppose the alternative option (from a performance perspective) would be to not use Spring beans but declare the DAO's as #applicationScoped and inject them into the SuperBean class using JEE's CDI. Would this be better performance-wise?
In the example above it looks serviceTemplate is providing an example of what you want. Note the parent="serviceTemplate". You need to do something similar to those who inherit from superbean. There are other options but since you have working code in the serviceTemplate that might be the best place to start. Then read here for more details: