Introduction of the Spring

Spring is an open source framework that is a layered JavaEE one-stop framework.

The one-stop framework means that Spring has every layer of solutions that JavaEE develops.

  • The WEB tier: for SpringMVC
  • Service layer: Spring’s Bean management, declarative transactions
  • DAO layer: Spring’s JDBC template, ORM template

Advantages:

  • IOC: Easy to decouple
  • AOP: Extend the program
  • Lightweight framework
  • Easy integration with other frameworks

Spring source code

Spring use

The directory for decompressing the Spring development package is as follows:

  • Docs: Spring development specification and API
  • Libs: Spring JAR package and source code
  • Schema: Constraints on the Spring configuration file

Inversion of Control (IOC)

Inversion of Control refers to an Inversion of creation rights for an object to Spring.

Use IOC will need to import the IOC related packages, the core of the above several packages in the container: beans, the context, the core, expression of four packages.

Basic concept

In Java development, Ioc means handing your designed objects over to the container for control, rather than the traditional direct control within your objects.

In traditional Java SE programming, we create objects directly inside the object through new, and the program actively creates dependent objects. IoC, on the other hand, has a container to create these objects, that is, the IoC container controls object creation.

In traditional applications, we have our own active control in the object to get the dependent object directly, that is, forward transformation; In inversion, the container helps create and inject dependent objects. Why reverse? Because the container helps us find and inject the dependent object, the object only passively accepts the dependent object, so it is inversion; What has been reversed? The retrieval of dependent objects has been reversed.

Realize the principle of

The traditional way to create an object:

UserDAO userDAO=new UserDAO();
Copy the code

Further interface oriented programming can be polymorphic:

UserDAO userDAO=new UserDAOImpl();
Copy the code

The disadvantage of this approach is that the interface and implementation class are highly coupled, and the source code needs to be modified when switching the underlying implementation class. The program design should meet the OCP primitive, and expand the program without modifying the program source code as far as possible. At this point, you can use factory mode:

class BeanFactory{
    public static UserDAO getUserDAO(a){
        return newUserDAOImpl(); }}Copy the code

In this way there is no coupling between the interface and the implementation class, but there is coupling between the interface and the factory.

Decoupling is achieved using a factory + reflection + configuration file approach, which is also the underlying implementation of the Spring framework IOC.

// XML configuration file
//<bean id="userDAO" class="xxx.UserDAOImpl"></bean>
class BeanFactory{
    public static Object getBean(String id){
        / / to parse the XML
        / / reflection
        Class clazz=Class.forName();
        returnclazz.newInstance(); }}Copy the code

The IOC XML development

The xSD-configuration. HMTL file is included in the docs file. Beans Schema is defined.

<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"> // Configure bean <bean id= here"userService" class="x.y.UserServiceImpl">
    </bean>

</beans>
Copy the code

Call the class:

ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService)applicationContext.getBean("userService");
userService.save();
Copy the code

The IOC and DI

DI refers to dependency injection, which requires an IOC environment. Spring manages this class by injecting the properties of the class’s dependencies.

For example, in userServiceImp.java:

public class UserServiceImpl implements UserService{
	private String name;
	
	public void setName(String name){
		this.name=name;
	}
	public void save(a){
		System.out.println("save "+name); }}Copy the code

In the configuration file:

<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="userService" class="spring.demo1.UserServiceImpl">
    <! -- Configure dependent properties -->
    	<property name="name" value="tony"/>
    </bean>

</beans>
Copy the code

Test code:

@Test
	public void demo2(a){
		// Create a Spring factory
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
		UserService userService=(UserService)applicationContext.getBean("userService");
		userService.save();
	}
Copy the code

Running results:

save tony
Copy the code

As you can see, the properties configured in the configuration file have their dependent properties successfully set when Spring manages the class. If you don’t use dependency injection, you can’t use the interface, you have to use the implementation class to set it up, because the interface doesn’t have this property.

Spring’s factory class

  • BeanFactory: Old version of the factory class, in the callgetBean()Method, an instance of the class is generated.
  • ApplicationContext: All spring-managed classes are instantiated when the configuration file is loaded. There are two implementation classes:
    1. ClassPathXmlApplicationContext: load the classpath configuration file
    2. FileSystemXmlApplicationContext: under loading disk configuration file

Bean label configuration

  • Id: unique constraint that cannot contain special characters
  • Name: Theoretically repeatable, but preferably not in development. Special characters can appear

Life cycle:

  • Init-method: The method executed when the bean is initialized
  • Destroy-method: The method executed when the bean is destroyed

Scope of action:

  • Scope: The scope of a bean. There are several types of scope, the first two are commonly used
    • Singleton: Created using singleton mode by default
    • Prototype: more cases
    • Request: In a Web project, spring creates a class and stores it in the Request scope
    • Session: In a Web project, spring creates classes and stores them in the Session scope
    • Globalsession: Must be used in a portlet environment in a Web project

Property injection Settings

  1. Constructor – style property injection: The Car class has two properties in the constructor, name and price.
<bean id="car" class="demo.Car">
    <constructor-arg name="name" value="bmw">
    <constructor-arg name="price" value="123">
</bean>
Copy the code
  1. Set method property injection: The Employee class has two set methods, one for the common type name and the other for the reference type Car (with ref pointing to the id or name of the reference type).
<bean id="employee" class="demo.Employee">
    <property name="name" value="xiaoming">
    <property name="car" ref="car">
</bean>
Copy the code
  1. Attribute injection for the P namespace: first we need to introduce the P namespace:
<beans xmlns="http://www.springframework.org/schema/beans"/ / introductionpThe namespacexmlns:p="http://www.springframework.org/schema/p"
    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">
</beans>
Copy the code

If it is a common property:

<bean id="car" class="demo.Car" p:name="bmv" p:price="123">
</bean>
Copy the code

If it is a reference type:

<bean id="employee" class="demo.Employee" p:name="xiaoming" p:car-ref:"car">
</bean>
Copy the code
  1. SpEL(Spring Expression Language) Property injection (Spring 3.x later)
<bean id="car" class="demo.Car">
    <property name="name" value="#{'xiaoming'}">
    <property name="car" ref="#{car}">
</bean>
Copy the code
  1. Collection type attribute injection:
<bean id="car" class="demo.Car">
    <property name="namelist">
        <list>
            <value>qirui</value>
            <value>baoma</value>
            <value>benchi</value>
        </list>
    </property>
</bean>
Copy the code

Multi-module development configuration

  1. When loading a configuration file, load multiple configuration files
  2. To introduce multiple configuration files in a configuration file by implementing

IOC annotation development

The sample

  1. Introducing JAR packages: In addition to the four packages described above, you will also need to introduce an AOP package.
  2. Create ApplicationContext.xml and use annotation development to introduce context constraints (xsD-configuration.html)
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 
        <! -- bean definitions here -->
</beans>
Copy the code
  1. Component scanning: Developed using IOC annotations, component scanning needs to be configured, that is, which classes under packages use IOC annotations.
<context:component-scan base-package="demo1">
Copy the code
  1. Add annotations to the class

  2. Use annotations to set the value of the property

Property If there is a set method, add the annotation injected by the property to the set method

Attribute has no set method. Add annotations to the attribute.

@Component("UserDao")// A 
      
        is configured with the id of UserDao and the corresponding class as UserDao
      
public class UserDAOImpl implements UserDAO {

	@Override
	public void save(a) {
		// TODO Auto-generated method stub
		System.out.println("save"); }}Copy the code

Annotations,

1.@Component

Component annotations, used to modify a class that Spring manages.

There are three derived annotations that perform similar functions and also modify classes.

  • Controller: Decorates the Web layer class
  • @service: Decorates the Service layer class
  • @repository: Decorates dao layer classes

Property injection

  • Common properties use @value to set the Value of the property
  • Object attributes use @AutoWired, which is an annotation for property injection by type. If you want to inject properties based on the bean name or ID, you need to use @Autowired in conjunction with @Qualifier
  • In real development, @resource (name=” “) is used to complete property injection by object name

3. Other notes

  • @postconstruct is equivalent to init-method and is used to initialize annotations to functions
  • @predestroy is equivalent to destroy-method and is used to destroy the annotation of the function
  • @scope (“prototype”) @scope (“prototype”)

Comparison of XML and annotation development for IOC

  • Application scenario: XML is suitable for any scenario; Annotations are only appropriate for classes that you write, not for classes that you do not provide.
  • You can use XML management beans, using annotations for property injection

Comparison between IOC and traditional methods

  1. How to get objects: Traditionally, an object is actively created using the new keyword. In IOC mode, the object lifecycle is managed by Spring and objects are obtained directly from Spring. That is, inversion of control ———— takes control out of your hands and gives it to Spring.

AOP development

AOP is the abbreviation of Aspect Oriented Programming, which means section-oriented Programming. It is a kind of technology that realizes unified maintenance of program functions through pre-compilation and run-time dynamic proxy, and it is an extension of OOP.

AOP can enhance the program, without modifying the source code, permission verification, logging, performance monitoring, transaction control, and so on.

In other words, functions are divided into two categories, one is core business functions, and the other is auxiliary enhancement functions. The two classes of functionality are developed independently of each other. For example, the login function is a core business function, and the logging function is a secondary enhancement function. If necessary, log and login can be compiled together. Auxiliary functions are called facets, and this selective, low-coupling approach to programming that combines facets with core business functions is called facets programming.

The purpose of the AOP

DRY: Dont Repeat Yourself SoC: Sepration of Concerns

  • Horizontal separation: Display layer -> Services Layer -> Persistence layer
  • Vertical separation: module division
  • Sectioning: Separating functional and non-functional requirements

Why use AOP

  • Focus on one concern/crosscutting logic
  • Easy to add/remove concerns
  • Less intrusive, improved code readability and maintainability

Mainly used in permission control, cache control, transaction control, audit log, performance monitoring, distributed tracing, exception handling and so on.

The underlying implementation

JDK dynamic proxies can only generate proxies for classes that implement interfaces. Cglib dynamic proxies can generate proxy objects for classes that do not implement interfaces, generating subclass objects.

JDK dynamic proxy

JDK dynamic proxies are implemented based on interfaces, underlying reflection.

public interface Subject {
    public void request(a);
}
Copy the code

Implementation class:

public class RealSubject implements Subject {
    @Override
    public void request(a) {
        System.out.println("real subject request"); }}Copy the code

The JDK agent:

public class JdkProxySubject implements InvocationHandler {

    private RealSubject realSubject;

    public JdkProxySubject(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before");
        Object result = null;
        try {
            result = method.invoke(realSubject, args);
        } catch (Exception e) {
            throw e;
        } finally {
            System.out.println("after");
        }
        returnresult; }}Copy the code

The test class

public class Client {
    public static void main(String[] args) {
        RealSubject rs=new RealSubject();
        InvocationHandler handler=newJdkProxySubject(rs); Subject subject=(Subject) Proxy.newProxyInstance(rs.getClass().getClassLoader(),rs.getClass().getInterfaces(),handler); subject.request(); }}Copy the code

Running results:

before
real subject request
after
Copy the code

In the Client, the Proxy object is generated by calling proxy.newProxyInstance (). The parameters are classLoader, the interface to be proxied, and the InvocationHandler for the Proxy object. When subject.request() is called, the invoke method in JdkProxySubject is actually called.

Cglib

Cglib is a third-party open source generation library that dynamically adds class properties and methods.

JDK proxies are implemented based on interfaces, while Cglib is implemented based on inheritance:

public class Hello {
    public void hello(String str){
        System.out.println("hello "+str); }}Copy the code

This class does not implement any interface. The CGLIB proxy implements this: First, a MethodInterceptor is implemented, and method calls are forwarded to the Intercept () method of that class. The proxy object is then retrieved through the CGLIB dynamic proxy when the class is needed.

class MyMethodInterceptor implements MethodInterceptor{...@Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        logger.info("You said: " + Arrays.toString(args));
        returnproxy.invokeSuper(obj, args); }}Copy the code
public class Test {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
				enhancer.setSuperclass(HelloConcrete.class);
				enhancer.setCallback(new MyMethodInterceptor());

				HelloConcrete hello = (HelloConcrete)enhancer.create();
				System.out.println(hello.sayHello("I love you!")); }}Copy the code

Through additional Enhancer to specify a target, the actual processing of the agency to logical object, finally through a call to the create () method to get a proxy object, the object of all the final method call will be forwarded to MethodInterceptor. Intercept () method.

Both are

When to use JDK or CGLiB?

  • If the target object implements an interface, the JDK’s dynamic proxy implementation of AOP is used by default.
  • You can force CGLIB to implement AOP if the target object implements an interface.
  • If the target object does not implement an interface and must use the CGLIB library, Spring automatically converts between JDK dynamic proxies and CGLIB.

How does Spring choose to use JDK or CGLiB?

  • Spring uses the JDK’s dynamic proxy when the Bean implements the interface.
  • Spring uses CGlib as an implementation when the Bean does not implement the interface.
  • You can force the use of CGlib (add < AOP: Aspectj-autoproxy proxy-target-class=”true”/> in your Spring configuration).

AOP development in Spring (AspectJ’s XML approach)

AspectJ is an AOP framework. Spring introduces AspectJ and implements AOP development based on AspectJ.

Related terms

  • Joinpoint: a Joinpoint that can be intercepted. The point at which a program is allowed to insert an aspect at runtime. This can be a function, a package path, a class, or an exception thrown
  • Pointcut: Pointcut, used to specify the range of join points, which are actually intercepted, and which methods are actually enhanced
  • Advice: defines the operations of the aspect near the pointcut, i.e. when and what to do. Before, after, etc.
  • Aspect: an aggregation of aspects, pointcuts, and advice, typically a class abstracted from common logic across many classes that define when, where, and what to do.
  • Introduction: Class level enhancement.
  • Target: the object (class) to be enhanced, that is, the object to be textured into.
  • Weaving: Weaving is the process of applying a cut surface to the connecting points of the cut. The section is woven into the target object at the specified join point.
  • Proxy: a Proxy object that is enhanced.

Method of use

  1. Importing related packages
  2. Importing a 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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <! -- bean definitions here -->

</beans>
Copy the code
  1. Write the target class and configure:
public class ProductDaoImpl implements ProductDao {
	@Override
	public void save(a) {
		System.out.println("save");
	}
	@Override
	public void update(a) {
		System.out.println("update");
	}
	@Override
	public void find(a) {
		System.out.println("find");
	}
	@Override
	public void delete(a) {
		System.out.println("delete"); }}Copy the code
<bean id="productDao" class="demo1.ProductDaoImpl"></bean>
Copy the code
  1. Write aspect classes, presumably for permission validation and configuration
public class MyAspectXML {
	public void checkPri(a){
		System.out.println("check auth"); }}Copy the code
<bean id="myAspect" class="demo1.MyAspectXML"></bean>
Copy the code
  1. Enhancements to the target classes are accomplished through an AOP configuration
	<aop:config>
		<aop:pointcut expression="execution(* demo1.ProductDaoImpl.save(..) )" id="pointcut1"/>
		
		<aop:aspect ref="myAspect">
			<aop:before method="chechPri" pointcut-ref="pointcut1"/>
		</aop:aspect> 
	</aop:config>
Copy the code

Notification type

  1. Pre-notification: Action before the target method executes to obtain pointcut information
<aop:before method="chechPri" pointcut-ref="pointcut1"/>
Copy the code
public void checkPri(JoinPoint joinPoint){
	System.out.println("check auth "+joinPoint);
}
Copy the code
  1. Post notification: After the target method is executed, the method return value can be obtained
<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/>
Copy the code
public void writeLog(Object result){
    System.out.println("writeLog "+result);
}
Copy the code
  1. Circular notification: Actions before and after target method execution can prevent target method execution
<aop:around method="around" pointcut-ref="pointcut3"/>
Copy the code
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
	System.out.println("before");
	Object result=joinPoint.proceed();
	System.out.println("after");
	return result;
}
Copy the code
  1. Exception throw notification: Action when an exception occurs in the program
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
Copy the code
public void afterThrowing(Throwable ex){
		System.out.println("exception "+ex.getMessage());
	}
Copy the code
  1. Final notification: equivalent to a finally block that executes regardless of whether the code has an exception
<aop:after method="finallyFunc" pointcut-ref="pointcut4"/>
Copy the code
public void finallyFunc(a){
	System.out.println("finally");
}
Copy the code
  1. Referral notices: not often used

Spring pointcut expression

Done based on the execution function

Syntax: The package name returned by the access modifier method. Class name. Method name (parameter)

Any field can use * instead of any value

Spring’s AOP is developed based on AspectJ annotations

Development steps

  1. The introduction of the jar package
  2. Setting up 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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>
Copy the code
  1. Write the configuration target class
<bean id="orderDao" class="demo1.OrderDao"></bean>
Copy the code
public class OrderDao {
	public void save(a){
		System.out.println("save order");
	}
	
	public void update(a){
		System.out.println("update order");
	}
	public void delete(a){
		System.out.println("delete order");
	}
	public void find(a){
		System.out.println("find order"); }}Copy the code
  1. Enable aop annotation automatic proxy
<aop:aspectj-autoproxy/>
Copy the code
  1. Write the aspect class and configure it
@Aspect
public class MyAspectAnno {
	
	@Before(value="execution(* demo1.OrderDao.save(..) )")
	public void before(a){
		System.out.println("before"); }}Copy the code
<bean id="myAspect" class="demo1.MyAspectAnno">
Copy the code

Annotation type

Notes fall into three main categories:

  1. @aspect: indicates that this is a section class
  2. @pointcut: Represents a Pointcut, which is a class or method that needs to be enhanced

This annotation needs to be composed with a section expression. A section expression is made up of three parts: designators, wildcards, and operators.

Indicators are divided into:

  • Match method: Execution ()
Execution ([modifier-pattern]// ret-type-pattern// Return type [modifier-pattern]// Package name-pattern(param-pattern)// Method name [throws exception declaration]Copy the code
  • Matching annotations: @target(),@args(),@within(),@annotation()
  • Matching package/class: Within ()
@Pointcut("within(demo.service.*)")
public void pointcut(a){}
Copy the code
  • Match objects: this(),bean(),target()
  • Matching parameter: args()
// Matches any method that takes only one Long argument
@Pointcut("args(Long)")
// Matches methods whose first argument is Long
@Pointcut("args(Long,..) ")
Copy the code

The wildcards are:

    • Matches any number of characters
    • Matches the specified class and its child columns
  • . Use to match any number of subpackages or parameters

Operators are mainly &&, | |,! That is, and or not three.

  1. Advice: When should an enhanced approach be implemented
  • @before: Pre-notification
  • @afterreturning: Post notification
@AfterReturning(value="execution(* demo1.OrderDao.save(..) )",returning="result")
public void after(Object result){
	System.out.println("after "+result);
}
Copy the code
  • @around: Circular notification
@Around(value="execution(* demo1.OrderDao.save(..) )")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
		System.out.println("before");
		Object obj=joinPoint.proceed();
		System.out.println("after");
		return obj;
	}
Copy the code
  • @afterThrowing: Throws an exception
@AfterThrowing(value="execution(* demo1.OrderDao.save(..) )",throwing="e")
public void afterThrowing(Throwable e){
	System.out.println("exception:"+e.getMessage();
}
Copy the code
  • @after: Final notice
@After(value="execution(* demo1.OrderDao.save(..) )")
	public void after(a){
		System.out.println("finally");
	}
Copy the code
  • PointCut: PointCut annotations
@PointCut(value="execution(* demo1.OrderDao.save(..) )")
	private void pointcut1(a){}
Copy the code

The advantage of annotations is that you only need to maintain pointcuts, rather than modify each annotation as you modify it.

Spring’s JDBC template

Spring also provides solutions for the persistence layer, namely ORM modules and JDBC templates. For JDBC, provides the org. Springframework. JDBC. Core. The JdbcTemplate as template class.

Using JDBC Templates

  1. Introduce JAR packages, database drivers, and Spring jDBC-related packages.
  2. Basic use:
public void demo1(a){
    // Create a connection pool
	DriverManagerDataSource dataSource=new DriverManagerDataSource();
	dataSource.setDriverClassName("com.mysql.jdbc.Driver");
	dataSource.setUrl("jdbc:mysql:///spring4");
	dataSource.setUsername("root");
	dataSource.setPassword("123456");
	
	// Create a JDBC template
	JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
	jdbcTemplate.update("insert into account values (null,? ,?) "."xiaoming".1000d);
	}
Copy the code
  1. Hand over connection pooling and templates to Spring for management
  • Configuration file:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource;">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql:///spring4"></property>
		<property name="username" value="root"></property>
		<property name="password" value="123456"></property>
	</bean>
	
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate;"> 
		<property name="dataSource" ref="dataSource"></property>
	</bean>
Copy the code
  • Test file:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcDemo2 {
	
	@Resource(name="jdbcTemplate")
	private JdbcTemplate jdbcTemplate;
	
	@Test
	public void demo2(a){
		jdbcTemplate.update("insert into account values (null,? ,?) "."xiaolan".1000d); }}Copy the code

Use open source database connection pools

  1. Configuration using DBCP:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="JDBC: mysql: / / 192.168.66.128 spring4"></property>
		<property name="username" value="root"></property>
		<property name="password" value="123456"></property>
Copy the code
  1. Using C3P0 configuration:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="JDBC: mysql: / / 192.168.66.128 spring4"></property>
		<property name="user" value="root"></property>
		<property name="password" value="123456"></property>
	</bean>
Copy the code
  1. Import external properties files

Create the external properties file first:

JDBC. DriverClass = com. Mysql, JDBC Driver. JDBC url = JDBC: mysql: / / 192.168.66.128 spring4 JDBC username = root jdbc.password=123456Copy the code

Then configure the properties file:

<context:property-placeholder location="classpath:jdbc.properties"/>
	
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
		<property name="user" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>
Copy the code

CRUD operations

Insert, UPDATE, and DELETE statements all operate with the help of the template’s UPDATE method.

public void demo(a){
	jdbcTemplate.update("insert into account values (null,? ,?) "."xiaoda".1000d);
	jdbcTemplate.update("update account set name=? ,money=? where id=?"."xiaoda".1000d,2);
	jdbcTemplate.update("delete from account where id=?".6);
}
Copy the code

Query operation:

public void demo3(a){
		String name=jdbcTemplate.queryForObject("select name from account where id=?",String.class,5);
		long count=jdbcTemplate.queryForObject("select count(*) from account",Long.class);
	}
Copy the code

Encapsulate the returned result as a class:

public void demo4(a){
	Account account=jdbcTemplate.queryForObject("select * from account where id=?".new MyRowMapper(),5);
}
Copy the code

Among them:

class MyRowMapper implements RowMapper<Account>{

	@Override
	public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
		Account account=new Account();
		account.setId(rs.getInt("id"));
		account.setName(rs.getString("name"));
		account.setMoney(rs.getDouble("money"));
		returnaccount; }}Copy the code

Spring transaction management

The transaction

A transaction is a logical set of operations in which the units that make up the operation either all succeed or all fail.

It has four characteristics:

  • Atomicity: Transactions are indivisible
  • Consistency: Data integrity remains consistent before and after a transaction is executed
  • Isolation: The execution of a transaction should not be interrupted by other transactions
  • Persistence: Data is persisted to the database once the transaction ends

Security issues arise if isolation is not considered:

  • Read the questions:
    • Dirty read: a transaction reads uncommitted data from another transaction
    • Non-repeatable read: A transaction reads update data that has been committed by another transaction, resulting in inconsistent results for multiple queries in one transaction
    • Phantom read: a transaction reads insert data already committed by another transaction, resulting in inconsistent results for multiple queries within a transaction
  • Write questions:
    • Lost update

Resolve read problems: Set transaction isolation level

  • Read uncommitted: No Read problem can be solved
  • Read COMMITTED: Indicates that Read is committed to solve dirty Read problems
  • Repeatable Read: Solves the problems of dirty and unrepeatable read
  • Serializable: serializes all read issues

Transaction Management API

  1. PlatformTransactionManager: the platform transaction manager

This is an interface, with a number of different implementation classes, such as DataSourceTransactionManager underlying use JDBC management affairs; HibernateTransactionManager underlying use Hibernate management affairs.

  1. TransactionDefinition: TransactionDefinition information

Used to define information about a transaction, such as isolation level, timeout information, propagation behavior, whether it is read-only, and so on

  1. TransactionStatus: TransactionStatus

An object used to record the state of a transaction during transaction management.

When Spring conducts transaction management, the platform transaction manager firstly performs transaction management according to the transaction definition information. In the process of transaction management, various states are generated and these state information is recorded in the object of transaction state.

Propagation behavior of transactions

The propagation behavior of transactions mainly solves the problem of Service invocation, that is, how to operate when different transactions exist in different businesses.

Spring provides seven types of transaction propagation behavior, divided into three categories:

  • Ensure multiple operations are in the same transaction
    • 5, PROPAGATION_REQUIRED: The B method calls A method, and if A has A transaction, uses the transaction in A and includes the operations in B in that transaction. Otherwise, create A new transaction that includes the operations in A and B. (the default)
    • PROPAGATION_SUPPORTS: If A has A transaction, use A’s transaction. Otherwise, transactions are not used
    • PROPAGATION_MANDATORY: If A has A transaction, use A’s transaction. Otherwise throw an exception
  • Ensure that multiple operations are not in the same transaction
    • PROPAGATION_REQUIRES_NEW: If there is A transaction in A, suspend it and create A new transaction that contains only its own operations. Otherwise, create a new transaction that contains only its own operations.
    • 5, PROPAGATION_NOT_SUPPORTED: If A has A transaction, suspend, no transaction is used.
    • PROPAGATION_NEVER: If A has A transaction, throw an exception, meaning that A transaction cannot be run.
  • The nested transaction
    • Execute A transaction, PROPAGATION_NESTED: If A has A transaction, execute A transaction, and set A savepoint, and execute B’s operation. If an exception occurs, you can roll back to the original state or savepoint state.

The instance

Take transfer as an example, the DAO layer of the business layer is as follows:

public interface AccountDao {
	public void outMoney(String from,Double money);
	public void inMoney(String to,Double money);
}

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
	
	@Override
	public void outMoney(String from, Double money) {
		 this.getJdbcTemplate().update("update account set money = money - ? where name = ?",money,from);
	}

	@Override
	public void inMoney(String to, Double money) {
		this.getJdbcTemplate().update("update account set money = money + ? where name = ?",money,to); }}public interface AccountService {
	public void transfer(String from,String to,Double money);
}

public class AccountServiceImpl implements AccountService {

	private AccountDao accountDao;
	
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	
	@Override
	public void transfer(String from, String to, Double money) { accountDao.outMoney(from, money); accountDao.inMoney(to, money); }}Copy the code

Configuring classes in XML:

<bean id="accountService" class="tx.demo.AccountServiceImpl">
		<property name="accountDao" ref="accountDao"/>
	</bean>
	
	<bean id="accountDao" class="tx.demo.AccountDaoImpl">
		<property name="dataSource" ref="dataSource"/>
	</bean>
Copy the code

Transaction Management 1: Programmatic transaction management

  1. Configure the platform transaction manager
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
</bean>
Copy the code
  1. Configure the transaction management template class
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
	<property name="transactionManager" ref="transactionManager"></property>
</bean>
Copy the code
  1. Inject transaction management templates at the business layer
<bean id="accountService" class="tx.demo1.AccountServiceImpl">
	<property name="accountDao" ref="accountDao"/>
	<property name="transactionTemplate" ref="transactionTemplate"/>
</bean>
Copy the code
  1. The code implements transaction management
/ / ServiceImpl class:
private TransactionTemplate transactionTemplate;
@Override
public void transfer(String from, String to, Double money) {
	transactionTemplate.execute(new TransactionCallbackWithoutResult() {
	@Override
	protected void doInTransactionWithoutResult(TransactionStatus arg0) { accountDao.outMoney(from, money); accountDao.inMoney(to, money); }}); }Copy the code

Declarative transaction management (configured implementation, AOP based)

  1. Declarative transaction management in XML
  • Configure the transaction manager
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
</bean>
Copy the code
  • Configuring transaction Notification
<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<tx:attributes>
		<tx:method name="transfer" propagation="REQUIRED"/>
	</tx:attributes>
</tx:advice>
Copy the code
  • Configuring AOP Transactions
<aop:config>
	<aop:pointcut expression="execution(* tx.demo2.AccountServiceImpl.*(..) )" id="pointcut1"/>
	<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
Copy the code
  1. Annotation way
  • Configure the transaction manager, as above
  • Note to enable transaction management:
<tx:annotation-driven transaction-manager="transactionManager"/>
Copy the code
  • Add a annotation @Transactional on classes that use transactions