Spring spring and Java Web Integration

I. overview

When integrating Spring with Java Web, Spring can accomplish the following tasks:

1)Spring to control transactions (Dao jdbctemplate)

2) All components autowrapped

3) Manage database

1.1 steps of integration

1. guide pack

2. write configuration

1) add all components to the container and obtain them correctly

@Controller: servlet layer, which cannot be labeled in the servlet layer at present (a servlet will be created when Tomcat starts, and a new servlet will be created when annotation is used)
@Service: business logic layer
 @Repository: dao layer
 @Component: other components

2) automatic assembly between each component

3) configure declarative transactions

Transaction manager control database connection pool

4) IOC creation and destruction should be completed at the right time -- use the listener to start the container.

Project launch{
    IOC creation completed
}

Project destruction{
    
  IOC destruction
}

You can write a listener to do this. Spring has written the listener. The IOC container created by this listener is in ContextLoader (this property is IOC container). There is a static method to get: getCurrentWebApplicationContext.

private WebApplicationContext context;

3. test

2, Integrated experiment

Take the previous book city as an example:

1. Import package: the package needed to import Spring

spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar

2. Write configuration:

1) add all components to the container and get them correctly. First, create the configuration file of Spring, and select the required namespace in the configuration file:

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

  <context:component-scan base-package="com.atguigu"></context:component-scan>

</beans>

According to the above, annotate the business logic layer and Dao layer, as follows:

@Repository
public class BookDaoImpl extends BaseDaoImpl<Book> implements BookDao{...}

@Service
public class BookServiceImpl implements BookService{...}

//Note that annotations are written on implementation classes, not interfaces

2) each component is automatically assembled, as shown in the following two cases:

  • Using @ Autowired direct injection in annotated classes
  • In Servlet (no annotation), call method to get component (this method is written in a class for all Servlet calls). Because Tomcat will create a Servlet when it starts, the Servlet will call this method, create an IOC container in this method, and obtain the Service component from the IOC container).
//There are two situations. One is to directly inject @ Autowired annotation into annotated classes

@Service
public class BookServiceImpl implements BookService {

	@Autowired
	private BookDao bookDao;
    ...
}

//The other is to use special methods to obtain the
public class BookServlet extends BaseServlet {
	private static final long serialVersionUID = 1L;

	private BookService bookService=WebUtils.getBean(BookService.class);
    ...
}

//Because after Tomcat is started, servlets will be created first, and then these servlets will want to get services, and this method will be called. This method will create IOC containers, and then get Service components from the containers
public class WebUtils {
	
   private static ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
	/*
	 * Get components from IOC container
	 */
		public static <T>T getBean(Class<T> clazz){
			return ioc.getBean(clazz);
			
		}
   ...
}

3) configure declarative transactions

The transaction manager controls the database connection pool.

(1) first, configure the data source and JdbcTemplate in the configuration file:

<!-- Reference external profile -->
  <context:property-placeholder location="classpath:dbconfig.properties"/> 
  <!-- 1.Configure data sources -->
  <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSoure">
     <property name="user" value="${jdbc.user}"></property>
     <property name="password" value="${jdbc.password}"></property>
     <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
     <property name="driverClass" value="${jdbc.driverClass}"></property>
  </bean>
  <!-- 2.JdbcTemplate Operation database -->
  <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
     <constructor-arg name="dataSource" ref="dataSoure"></constructor-arg>
  </bean>
  

(2) next, change the Dao layer implementation class, because the logic written before is that all Dao implementation classes inherit the BaseDao implementation class. For the convenience of change, all changes are made in the BaseDao implementation class. Use the JdbcTemplate in this class to operate the database.

@Repository
public abstract class BaseDaoImpl<T> {

	
//	protected QueryRunner queryRunner;
	@Autowired
	private JdbcTemplate jdbcTemplate;
	/**
	 * Save the generic object class type of basedaimpl class
	 */
	protected Class<T> type;

	@SuppressWarnings("unchecked")
	public BaseDaoImpl() {
		// Create a QueryRunner object instance
	
		// Get the class type of the parent class with generics in the parent class
		ParameterizedType supperClass = (ParameterizedType) getClass().getGenericSuperclass();
		// Get the class of the specific type in the generic
		type = (Class<T>) supperClass.getActualTypeArguments()[0];
	}

	/**
	 * Execute update, delete and insert statements
	 * 
	 * @param sql
	 *            sql statement to execute
	 * @param params
	 *            Parameters of executed sql statements
	 * @return True < br / >
	 *         false if execution fails
	 * @throws SQLException 
	 */
	public int update(String sql, Object... params) throws SQLException {
		int update=jdbcTemplate.update(sql,params);
		return update;
	}

	/**
	 * Execute the query statement and return only the first record
	 * 
	 * @param sql
	 *            sql statement to execute
	 * @param params
	 *            Parameters of executed sql statements
	 * @return Return the specific instance of the query object < br / >
	 *         If the query data does not exist, return null < br / >
	 *         Query failure also returns null
	 * @throws SQLException 
	 */
	public T queryOne(String sql, Object... params) throws SQLException {
	T Object=null;
	try {
		Object = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<T>(type),params);
	} catch (DataAccessException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return Object;
	}

	/**
	 * Execute query statement and return the collection of object instances after query
	 * 
	 * @param sql
	 *            sql statement to execute
	 * @param params
	 *            sql Parameters of statement
	 * @return It returns the found object set < br / >
	 *         Query failed return null
	 * @throws Exception 
	 */
	public List<T> queryList(String sql, Object... params) throws Exception {
		return jdbcTemplate.query(sql, new BeanPropertyRowMapper<T>(type),params);
	}

	
	/**
	 * Query statements with only one return value
	 * 
	 * @param sql
	 * @param params
	 * @return
	 * @throws Exception 
	 */
	public Object querySingleValue(String sql, Object... params) throws Exception {
		Object object=jdbcTemplate.queryForObject(sql, Object.class, params);
		return object;
	}

}

(3) configure the transaction manager and Xml based transactions in the configuration file (because it is not convenient to use annotation @ Transactional to configure transactions and add all methods)

 <!-- 3.Configure transaction manager -->
   <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="dataSourceTransactionManager">
     <property name="dataSource" ref="comboPooldeDataSource"></property>
   </bean>
   
  <!-- Configuration based transactions -->
  <aop:config>
      <aop:pointcut expression="execution(* com.atguigu.service.impl.*.*(..))" id="txPoint"/>
      <aop:advisor advice-ref="myTx" pointcut-ref="txPoint"/>
  </aop:config>
  <tx:advice id="myTx" transaction-manager="dataSourceTransactionManager">
      <tx:attributes>
         <tx:method name="*"/>
         <tx:method name="get*" read-only="true"/>
      </tx:attributes>
  </tx:advice>

(4) test: because the inventory quantity of books set in the database cannot be less than 0, when closing, select a book with inventory quantity of 0 to close, and it will jump to the exception interface to display closing failure. Because transaction management is added to all methods, when an exception occurs, the transaction rolls back and the data in the database will not be changed. Therefore, the above situation will succeed.

4) Use the listener to start the container. In the previous experimental steps, we invoked a method in Servlet to create the container and get the component through this container. This is easy to cause problems. For example, more containers can be created through reflection, or containers can be created when the project is started, but they are not destroyed when the project is closed, and constantly opening the project will consume memory. So use a listener to start the container, which Spring has created. To use, first register in web and XML:

   <!-- needed for ContextLoaderListener -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>

	<!-- Bootstraps the root web application context before servlet initialization -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
  

After successful registration, the components obtained in the Servlet are used as follows:

public static <T>T getBean(Class<T> clazz){
			//Get IOC container
			WebApplicationContext ioc=ContextLoader.getCurrentWebApplicationContext();
			return ioc.getBean(clazz);
			
		}

This allows the listener to start the container.

3. After the test is executed successfully, the page is as follows:

Published 83 original articles, won praise 11, visited 20000+
Private letter follow

Tags: Spring SQL Database JDBC

Posted on Mon, 13 Jan 2020 02:20:50 -0500 by marty_arl