Learning notes of Spring (dark horse)

1. spring overview

1.1 what is spring (understand)

Spring is a lightweight open source framework for layered Java SE/EE application full stack, with IoC (Inverse Of Control) and AOP (Aspect Oriented Programming) as the kernel.

It provides many enterprise application technologies such as presentation layer spring MVC, persistence layer spring JDBC template and business layer transaction management. It can also integrate many famous third-party frameworks and class libraries in the world, and gradually become the most used open source framework for Java EE enterprise applications

1.2 development history of spring (understanding)

Rod Johnson (father of spring)

The latest version of Spring 5 was released in September 2017 0 General Edition (GA)

1.3 advantages of spring (understanding)

Convenient decoupling and simplified development

AOP programming support

Declarative transaction support

Facilitate program testing

1.4 Spring architecture (understand)

2. spring quick start

2.1 Spring program development steps

① Import the coordinates of the basic package developed by Spring

② Write Dao interface and implementation class

③ Create Spring core configuration file

④ Configure UserDaoImpl in the Spring configuration file

⑤ Use Spring's API to get Bean instances

2.2 import the basic package coordinates of Spring development

<properties>
	<spring.version>5.0.5.RELEASE</spring.version>
</properties>
<!--Import spring of context Coordinates, context rely on core,beans,expression-->
<dependencies> 
    <dependency>  
        <groupId>org.springframework</groupId> 
        <artifactId>spring-context</artifactId> 
        <version>${spring.version}</version>
    </dependency>
</dependencies>

2.3 write Dao interface and implementation class

public interface UserDao {  
    public void save();
}
public class UserDaoImpl implements UserDao {  
        @Override  
        public void save() {
        	System.out.println("UserDao save method running....");
	}
}

2.4 create Spring core configuration file

Create the applicationContext.xml configuration file under the classpath (resources)

<?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">
</beans>

2.5 configure UserDaoImpl in Spring 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"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans      	             http://www.springframework.org/schema/beans/spring-beans.xsd">
   <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
</beans>

2.6 obtain Bean instances using Spring's API

@Test
public void test1(){
		ApplicationContext applicationContext = new  
             ClassPathXmlApplicationContext("applicationContext.xml");
             UserDao userDao = (UserDao) applicationContext.getBean("userDao");   				 userDao.save();
 }

3. Spring configuration file

3.1 basic configuration of bean tag

The configuration object is created by Spring.

By default, it calls the parameterless constructor in the class. If there is no parameterless constructor, it cannot be created successfully.

Basic properties:

id: Bean Instance in Spring Unique identification in the container
class: Bean Fully qualified name of

3.2 Bean tag range configuration

Scope: refers to the scope of the object. The values are as follows:

Value rangeexplain
singletonDefault, singleton
prototypeMultiple cases
requestIn the web project, Spring creates a Bean object and stores the object in the request field
sessionIn the web project, Spring creates a Bean object and stores the object in the session domain
global sessionIn the web project, the application is in the Portlet environment. If there is no Portlet environment, the global session is equivalent to the session
  • When the value of scope is singleton

Number of instantiations of Bean: 1

Bean instantiation timing: instantiate the configured bean instance when the Spring core file is loaded

## Bean lifecycle:
Object creation: when the application loads and creates a container, the object is created
 Object running: the object remains alive as long as the container is
 Object destruction: when the application unloads and destroys the container, the object is destroyed
  • When the value of scope is prototype

Number of Bean instantiations: multiple

Instantiation timing of Bean: instantiate Bean when calling getBean() method

## The lifecycle of a bean
 Object creation: creates a new object instance when using an object
 Object running: as long as the object is in use, it will always be alive
 Object destruction: when an object is not used for a long time, it is destroyed Java My garbage collector collected it

3.3 Bean lifecycle configuration

Init method: Specifies the name of the initialization method in the class

Destroy method: Specifies the name of the destroy method in the class

3.4 three methods of bean instantiation

  • Instantiate using the parameterless construction method

It will create class objects according to the default parameterless constructor. If there is no default parameterless constructor in the bean, the creation will fail

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
  • Factory static method instantiation

The static method of the factory returns the Bean instance

public class StaticFactoryBean {
    public static UserDao createUserDao(){    
    return new UserDaoImpl();
    }
}
<bean id="userDao" class="com.itheima.factory.StaticFactoryBean" 
      factory-method="createUserDao" />
  • Factory instance method instantiation

The non static method of the factory returns a Bean instance

public class DynamicFactoryBean {  
	public UserDao createUserDao(){        
		return new UserDaoImpl(); 
	}
}
<bean id="factoryBean" class="com.itheima.factory.DynamicFactoryBean"/>
<bean id="userDao" factory-bean="factoryBean" factory-method="createUserDao"/>

3.5 introduction to bean dependency injection

① Create UserService and call the save() method of UserDao internally

public class UserServiceImpl implements UserService {
	@Override
	public void save() {
         ApplicationContext applicationContext = new 
                 ClassPathXmlApplicationContext("applicationContext.xml");       	           			 UserDao userDao = (UserDao) applicationContext.getBean("userDao");	
         userDao.save();
 	}
 }

② Give Spring the right to create UserServiceImpl

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl"/>

③ Obtain UserService from Spring container for operation

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

3.6 dependency injection concept of bean

Dependency Injection: it is the concrete implementation of the Spring framework core IOC.

When writing the program, the creation of objects is handed over to Spring through control inversion, but there can be no dependency in the code.

IOC decoupling only reduces their dependencies, but it will not eliminate them. For example, the business layer will still call the methods of the persistence layer.

After using Spring, Spring can maintain the dependency between the business layer and the persistence layer.

Simply put, it means waiting for the framework to transfer the persistence layer object to the business layer without getting it ourselves

3.7 dependency injection method of bean

① Construction method

Create parametric structure

public class UserServiceImpl implements UserService {
	@Override
    public void save() {
        ApplicationContext applicationContext = new 
            ClassPathXmlApplicationContext("applicationContext.xml");      
        UserDao userDao = (UserDao) applicationContext.getBean("userDao");    
        userDao.save();
    }
 }

Configure the Spring container to inject when calling parameterized constructs

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">      		   			    <constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>

② set method

Add setUserDao method in UserServiceImpl

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;  
     } 
    @Override    
    public void save() {      
   		 userDao.save();
	}
}

Configure the Spring container to call the set method for injection

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
	<property name="userDao" ref="userDao"/>
</bean>

set method: P namespace injection

The essence of P namespace injection is also set method injection, but it is more convenient than the above set method injection, which is mainly reflected in the configuration file, as follows:

First, you need to introduce the P namespace:

xmlns:p="http://www.springframework.org/schema/p"

Secondly, the injection method needs to be modified

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl" p:userDao-
 ref="userDao"/>

3.8 Bean dependency injection data types

The above operations are all injected reference beans. In addition to object references, ordinary data types and collections can be injected in the container.

## Three data types of injected data 
Common data type
 Reference data type
 Collection data type

The reference data type will not be repeated here. The previous operations are to inject the reference of UserDao object. The following will take set method injection as an example to demonstrate the injection of common data type and set data type.

Data type of Bean dependency injection

(1) Injection of common data types

public class UserDaoImpl implements UserDao {
    private String company;
    private int age;
    
    public void setCompany(String company) {
        this.company = company;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void save() {
        System.out.println(company+"==="+age);
        System.out.println("UserDao save method running....");   
    }
}

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <property name="company" value="Intelligence Podcast"></property>
    <property name="age" value="15"></property>
</bean>

(2) Injection of collection data type (List)

public class UserDaoImpl implements UserDao {
	private List<String> strList;
	public void setStrList(List<String> strList) {
		this.strList = strList;
	}
	public void save() {
        System.out.println(strList);
        System.out.println("UserDao save method running....");
	}
}
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <property name="strList">
        <list>
            <value>aaa</value>
            <value>bbb</value>
            <value>ccc</value>
        </list>
    </property>
</bean>

(3) Injection of collection data type (List)

public class UserDaoImpl implements UserDao {
	private List<User> userList;
    
	public void setUserList(List<User> userList) {
	    this.userList = userList;  
    }
    public void save() {
        System.out.println(userList);
        System.out.println("UserDao save method running....");
	}
}
<bean id="u1" class="com.itheima.domain.User"/>
<bean id="u2" class="com.itheima.domain.User"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <property name="userList">
        <list>
            <bean class="com.itheima.domain.User"/>
            <bean class="com.itheima.domain.User"/>
            <ref bean="u1"/>
            <ref bean="u2"/>       
        </list>
    </property>
</bean>

(4) Injection of collection data type (map < string, user >)

public class UserDaoImpl implements UserDao {
    private Map<String,User> userMap;
    public void setUserMap(Map<String, User> userMap) {
    	this.userMap = userMap;
    }    
	public void save() {      
        System.out.println(userMap);
        System.out.println("UserDao save method running....");
	}
}
<bean id="u1" class="com.itheima.domain.User"/>
<bean id="u2" class="com.itheima.domain.User"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <property name="userMap">
        <map>            
            <entry key="user1" value-ref="u1"/>
            <entry key="user2" value-ref="u2"/>
        </map>
    </property>
</bean>

(5) Injection of collection data types (Properties)

public class UserDaoImpl implements UserDao {
    private Properties properties;
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
	public void save() {
		System.out.println(properties);
		System.out.println("UserDao save method running....");
	}
}
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <property name="properties">
        <props>
            <prop key="p1">aaa</prop>
            <prop key="p2">bbb</prop> 
            <prop key="p3">ccc</prop>
        </props>
    </property>
</bean>

3.9 introduction of other configuration files (sub module development)

In actual development, there are many Spring configurations, which leads to the complexity and volume of Spring configuration. Therefore, some configurations can be disassembled into other configuration files, and loaded in the Spring main configuration file through the import tag

<import resource="applicationContext-xxx.xml"/>

4. spring related API s

4.1 inheritance system of ApplicationContext

applicationContext: interface type, which represents the application context. Bean objects in the Spring container can be obtained through its instance

4.2 implementation class of ApplicationContext

1)ClassPathXmlApplicationContext

It loads the configuration file from the root path of the class. This is recommended

2)FileSystemXmlApplicationContext

It loads the configuration file from the disk path. The configuration file can be anywhere on the disk.

3)AnnotationConfigApplicationContext

When configuring container objects with annotations, you need to use this class to create a spring container. It is used to read annotations.

4.3 use of getBean () method

public Object getBean(String name) throws BeansException {  
	assertBeanFactoryActive();   
	return getBeanFactory().getBean(name);
}
public <T> T getBean(Class<T> requiredType) throws BeansException { 
    assertBeanFactoryActive();
	return getBeanFactory().getBean(requiredType);
}

Where, when the data type of the parameter is a string, it means that the Bean instance is obtained from the container according to the Bean id, and the return is Object, which needs to be forced.

When the data type of the parameter is Class, it means that Bean instances are matched from the container according to the type. When there are multiple beans of the same type in the container, this method will report an error

The getBean() method uses

ApplicationContext applicationContext = new 
            ClassPathXmlApplicationContext("applicationContext.xml");
  UserService userService1 = (UserService) applicationContext.getBean("userService");
  UserService userService2 = applicationContext.getBean(UserService.class);

5.Spring configuration data source

5.1 role of data source (connection pool)

Data source (connection pool) appears to improve program performance. Instantiate the data source in advance, initialize some connection resources, obtain the connection resources from the data source when using them, and return the connection resources to the data source after use.

Common data sources (connection pool): DBCP, C3P0, BoneCP, Druid, etc

Development steps

① Import the coordinates of the data source and database driven coordinates

② Create data source object

③ Set the basic connection data of the data source

④ Use the data source to obtain connection resources and return connection resources

5.2 manual creation of data source

① Coordinates of imported c3p0 and druid

<!-- C3P0 Connection pool -->
<dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
</dependency>
<!-- Druid Connection pool -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

① Import mysql database driver coordinates

<!-- mysql drive -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.39</version>
</dependency>

② Create C3P0 connection pool

@Test
public void testC3P0() throws Exception {
	//create data source
	ComboPooledDataSource dataSource = new ComboPooledDataSource();
	//Setting database connection parameters
    dataSource.setDriverClass("com.mysql.jdbc.Driver");  
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
    dataSource.setUser("root");
    dataSource.setPassword("root");
	//Get connection object
	Connection connection = dataSource.getConnection();
	System.out.println(connection);
}

② Create Druid connection pool

@Test
public void testDruid() throws Exception {
    //create data source
    DruidDataSource dataSource = new DruidDataSource();
    //Setting database connection parameters
    dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 
    dataSource.setUrl("jdbc:mysql://localhost:3306/test");   
    dataSource.setUsername("root");
    dataSource.setPassword("root");
    //Get connection object
    Connection connection = dataSource.getConnection();    
    System.out.println(connection);
}

③ Extract JDBC Properties configuration file

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root

④ Read JDBC Create a connection pool using the properties configuration file

@Test
public void testC3P0ByProperties() throws Exception {
    //Load jdbc.net under the classpath properties
    ResourceBundle rb = ResourceBundle.getBundle("jdbc");
    ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
    dataSource.setDriverClass(rb.getString("jdbc.driver"));   
    dataSource.setJdbcUrl(rb.getString("jdbc.url")); 
    dataSource.setUser(rb.getString("jdbc.username")); 
    dataSource.setPassword(rb.getString("jdbc.password"));
    Connection connection = dataSource.getConnection();   
    System.out.println(connection);
}

5.3 Spring configuration data source

  • You can leave the creation of the DataSource to the Spring container.

  • DataSource has a parameterless constructor, and Spring instantiates objects by default through the parameterless constructor

  • To use DataSource, you need to set the database connection information through the set method, and Spring can inject strings through the set method

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
    <property name="user" value="root"/>
    <property name="password" value="root"/>
</bean>
  • The test gets the data source from the container
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");   DataSource dataSource = (DataSource) applicationContext.getBean("dataSource");      
Connection connection = dataSource.getConnection();
System.out.println(connection);

5.4 extracting jdbc configuration files

applicationContext. Loading jdbc.xml Get the connection information from the properties configuration file.

First, you need to introduce the context namespace and constraint path:

Namespace:

xmlns:context="http://www.springframework.org/schema/context"

Constraint path:

http://www.springframework.org/schema/context   
http://www.springframework.org/schema/context/spring-context.xsd
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

5.5 key points of knowledge

The Spring container loads the properties file

<context:property-placeholder location="xx.properties"/>
<property name="" value="${key}"/>

6. Spring annotation development

6.1 Spring original annotation

  • Spring is a light code and heavy configuration framework. The configuration is heavy and affects the development efficiency. Therefore, annotation development is a trend. Annotation instead of xml configuration file can simplify the configuration and improve the development efficiency.

  • The Spring original annotation is mainly used to replace the Bean configuration

annotationexplain
@ComponentUsed on classes to instantiate beans
@ControllerUse to instantiate beans on web tier classes
@ServiceUsed on the service layer class to instantiate beans
@RepositoryUsed on dao layer classes to instantiate beans
@AutowiredUse on field for type dependent injection
@QualifierUsed in conjunction with @ Autowired for dependency injection by name
@ResourceEquivalent to @ Autowired+@Qualifier, injected by name
@ValueInject common attributes
@ScopeLabel the scope of the Bean
@PostConstructUse to label the method, which is the initialization method of the Bean
@PreDestroyUse to mark the method as the Bean's destruction method

be careful:

When developing with annotations, you need to use the application context Component scanning is configured in XML to specify which package and beans under its sub packages need to be scanned in order to identify classes, fields and methods configured with annotations.

<!--Annotated component scan-->
<context:component-scan base-package="com.itheima"></context:component-scan>

Using @ component or @ Repository to identify UserDaoImpl requires Spring to instantiate it.

//@Component("userDao")
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
    	System.out.println("save running... ...");
    }
}

Using @ component or @ Service to identify UserServiceImpl requires Spring to instantiate it

Use @ Autowired or @ Autowired+@Qulifier or @ Resource to inject userDao

//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
    /*@Autowired
    @Qualifier("userDao")*/
    @Resource(name="userDao")
    private UserDao userDao;
    @Override
    public void save() {       
   	  userDao.save();
    }
}

Use @ Value for string injection

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Value("Inject common data")
    private String str;
    @Value("${jdbc.driver}")
    private String driver;
    @Override
    public void save() {
        System.out.println(str);
        System.out.println(driver);
        System.out.println("save running... ...");
    }
}

Use @ Scope to label the Scope of the Bean

//@Scope("prototype")
@Scope("singleton")
public class UserDaoImpl implements UserDao {
   //Code omitted here
}

Use the @ PostConstruct annotation initialization method and the @ PreDestroy annotation destruction method

@PostConstruct
public void init(){
	System.out.println("Initialization method....");
}
@PreDestroy
public void destroy(){
	System.out.println("Destruction method.....");
}

6.2 new notes of spring

  • The above annotations cannot completely replace the xml configuration file. The configurations that need to be replaced by annotations are as follows:
Non custom Bean Configuration of:<bean>
load properties Configuration of files:<context:property-placeholder>
Configuration of component scanning:<context:component-scan>
Import other files:<import>
annotationexplain
@ConfigurationUsed to specify that the current class is a Spring configuration class from which annotations will be loaded when creating a container
@ComponentScanUsed to specify the package to be scanned by Spring when initializing the container The function is the same as < context: component scan base package = "com.itheima" / > in the xml configuration file of Spring
@BeanOn a method, annotations store the return value of the method in the Spring container
@PropertySourceFor loading Configuration in the properties file
@ImportUsed to import other configuration classes
@Configuration//Note that it is a configuration class
@ComponentScan("com.itheima")//Specify the packages to scan
@Import({DataSourceConfiguration.class})//Import other configuration classes
public class SpringConfiguration {
    .....
}
@PropertySource("classpath:jdbc.properties")//load. Configuration in the properties file
public class DataSourceConfiguration {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
@Bean(name="dataSource")//The return value of the method will be stored in the spring container. When used, it will be obtained from the container according to the bean name dataSource
public DataSource getDataSource() throws PropertyVetoException { 
    ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
    dataSource.setDriverClass(driver);
    dataSource.setJdbcUrl(url);
    dataSource.setUser(username);
    dataSource.setPassword(password);
    return dataSource;
} 

Test loading core configuration classes to create Spring containers

@Test
public void testAnnoConfiguration() throws Exception {
	ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);  
    UserService userService = (UserService)applicationContext.getBean("userService");    
    userService.save();
    DataSource dataSource = (DataSource) applicationContext.getBean("dataSource");
    Connection connection = dataSource.getConnection(); 
    System.out.println(connection);
    }

7. Spring integrates Junit

7.1 problems with the original Junit test Spring

In the test class, each test method has the following two lines of code:

 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
 IAccountService as = ac.getBean("accountService",IAccountService.class);

The purpose of these two lines of code is to obtain the container. If it is not written, a null pointer exception will be prompted directly. So it can't be deleted easily.

7.2 solutions to the above problems

Let Spring JUnit be responsible for creating the Spring container, but you need to tell it the name of the configuration file

The Bean that needs to be tested is injected directly into the test class

7.3 Spring integration Junit steps

① Import the coordinates of spring integration Junit

② Replace the original runtime with the @ Runwith annotation

③ Use @ ContextConfiguration to specify a profile or configuration class

④ Inject the object to be tested with @ Autowired

⑤ Create a test method to test

7.4 Junit code implementation of spring integration

① Import the coordinates of spring integration Junit

<!--It should be noted here that, spring5 And above version requirements junit The version of must be 4.12 And above-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

② Replace the original runtime with the @ Runwith annotation

@RunWith(SpringJUnit4ClassRunner.class)
public class SpringJunitTest {
}

③ Use @ ContextConfiguration to specify a profile or configuration class

@RunWith(SpringJUnit4ClassRunner.class)
//Load spring core configuration file
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//Load spring core configuration class
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
    
}

④ Inject the object to be tested with @ Autowired

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
    @Autowired
    private UserService userService;
}

⑤ Create a test method to test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})public class SpringJunitTest {
    @Autowired
    private UserService userService;
    @Test
    public void testUserService(){
   	 userService.save();
    }
}

8. AOP of spring

8.1 what is AOP

  • AOP is the abbreviation of Aspect Oriented Programming, which means Aspect Oriented Programming. It is a technology to realize the unified maintenance of program functions through precompiled mode and runtime dynamic agent.

  • AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework, and a derivative paradigm of functional programming. AOP can isolate each part of business logic, reduce the coupling between each part of business logic, improve the reusability of program, and improve the efficiency of development.

8.2 role and advantages of AOP

  • Function: during the running of the program, enhance the function of the method without modifying the source code

  • Advantages: reduce duplicate code, improve development efficiency, and easy to maintain

8.3 underlying implementation of AOP

  • In fact, the underlying layer of AOP is implemented through the dynamic proxy technology provided by Spring. During operation, Spring dynamically generates proxy objects through dynamic proxy technology. When the proxy object method is executed, it intervenes to enhance the function, and calls the method of the target object, so as to complete the function enhancement.

8.4 dynamic agent technology of AOP

Common dynamic agent technology

JDK agent: dynamic agent technology based on interface

cglib proxy: dynamic proxy technology based on parent class

8.5 dynamic agent of JDK

① Target class interface

public interface TargetInterface {
   public void method();
}

② Target class

public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}

③ Dynamic proxy code

Target target = new Target(); //Create target object
//Create proxy object
TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target.getClass()
.getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) 
            throws Throwable {
                System.out.println("Pre enhancement code...");
                Object invoke = method.invoke(target, args);
                System.out.println("Post enhancement code...");
                return invoke;
            }
        }
);

④ Call the method test of the proxy object

// When calling any method of the interface, the code of the proxy object is modified out of order
proxy.method();

8.6 dynamic proxy of cglib

① Target class

public class Target {
  public void method() {
      System.out.println("Target running....");
  }
}

② Dynamic proxy code

Target target = new Target(); //Create target object
Enhancer enhancer = new Enhancer();   //Create intensifier
enhancer.setSuperclass(Target.class); //Set parent class
enhancer.setCallback(new MethodInterceptor() { //Set callback
    @Override
    public Object intercept(Object o, Method method, Object[] objects, 
    MethodProxy methodProxy) throws Throwable {
        System.out.println("Pre code enhancement....");
        Object invoke = method.invoke(target, objects);
        System.out.println("Post code enhancement....");
        return invoke;
    }
});
Target proxy = (Target) enhancer.create(); //Create proxy object

③ Call the method test of the proxy object

//When calling any method of the interface, the code of the proxy object is modified out of order
proxy.method();

8.7 AOP related concepts

The bottom layer of Spring's AOP implementation is to encapsulate the code of the above dynamic agent. After encapsulation, we only need to code the parts that need attention, and complete the method enhancement of the specified goal through configuration.

Before formally explaining the operation of AOP, we must understand the relevant terms of AOP. The commonly used terms are as follows:

# term
Target(Target object): the target object of the proxy  
Proxy (Proxy): a class is AOP After weaving in the enhancement, a result proxy class is generated  
Joinpoint(Connection points): the so-called connection points refer to those intercepted points. stay spring in,These points refer to methods because spring Only connection points of method type are supported  
Pointcut(Entry point): the so-called entry point refers to what we want to do Joinpoint Definition of interception  
Advice(notice/ Enhanced): the so-called notification refers to the interception of Joinpoint Then all you have to do is inform  
Aspect(Aspect: it is the combination of entry point and notification (Introduction)  
Weaving(Weaving: refers to the process of applying enhancements to the target object to create a new proxy object. spring Dynamic proxy weaving is adopted, and AspectJ Compile time weaving and class load time weaving are adopted

8.8 clear matters for AOP development

1) What needs to be written
  • Write core business code (target method of target class)

  • Write a facet class with notifications (enhancement methods) in it

  • In the configuration file, configure the weaving relationship, that is, which notifications are combined with which connection points

2) Content of AOP technology implementation

The Spring framework monitors the execution of pointcut methods. Once it is monitored that the pointcut method is running, the proxy mechanism is used to dynamically create the proxy object of the target object. According to the notification category, the corresponding function of the notification is woven into the corresponding position of the proxy object to complete the complete code logic operation.

3) Which proxy method does the underlying AOP use

In spring, the framework will decide which dynamic proxy method to adopt according to whether the target class implements the interface.

8.9 key points of knowledge

  • aop: Aspect Oriented Programming

  • The underlying implementation of aop: dynamic agent based on JDK and dynamic agent based on Cglib

  • Key concepts of aop:

    Pointcut(Pointcuts): enhanced methods
    Advice(notice/ Enhanced): encapsulates methods for enhancing business logic
    Aspect(Tangent plane): tangent point+notice
    Weaving(Weaving: the process of combining pointcuts with notifications
    
  • Clear items for development:

    Who is the pointcut (pointcut expression configuration)
    Who is notification (enhancement method in facet class)
    Weaving pointcuts and notifications into configuration
    

9. AOP development based on XML

9.1 getting started

① Import AOP related coordinates

② Create target interface and target class (with internal tangent point)

③ Create facet class (with enhancement method inside)

④ Leave the object creation rights of the target class and the aspect class to spring

⑤ In ApplicationContext Configuring weaving relationships in XML

⑥ Test code

① Import AOP related coordinates

<!--Import spring of context Coordinates, context rely on aop-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.0.5.RELEASE</version>
</dependency>
<!-- aspectj Weaving in -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.8.13</version>
</dependency>

② Create target interface and target class (with internal tangent point)

public interface TargetInterface {
    public void method();
}

public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}

③ Create facet class (with enhancement method inside)

public class MyAspect {
    //Pre enhancement method
    public void before(){
        System.out.println("Pre code enhancement.....");
    }
}

④ Leave the object creation rights of the target class and the aspect class to spring

<!--Configure target class-->
<bean id="target" class="com.itheima.aop.Target"></bean>
<!--Configure facet class-->
<bean id="myAspect" class="com.itheima.aop.MyAspect"></bean>

⑤ In ApplicationContext Configuring weaving relationships in XML

Import aop namespace

<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"
       xsi:schemaLocation="
        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/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

Configure pointcut expressions and pre enhanced weaving relationships

<aop:config>
    <!--quote myAspect of Bean Is a tangent object-->
    <aop:aspect ref="myAspect">
        <!--to configure Target of method Method to execute myAspect of before Method pre enhancement-->
        <aop:before method="before" pointcut="execution(public void com.itheima.aop.Target.method())"></aop:before>
    </aop:aspect>
</aop:config>

⑥ Test code

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    @Autowired
    private TargetInterface target;
    @Test
    public void test1(){
        target.method();
    }
}

⑦ Test results

9.2 detailed explanation of XML configuration AOP

1) Writing of tangent point expression

Expression syntax:

execution([Modifier ] Return value type package name.Class name.Method name(parameter))
  • The access modifier can be omitted

  • The return value type, package name, class name and method name can be represented by an asterisk*

  • A point between the package name and the class name Represents the classes under the current package. Two points... Represent the classes under the current package and its sub packages

  • The parameter list can use two points... To represent any number and any type of parameter list

For example:

execution(public void com.itheima.aop.Target.method())	
execution(void com.itheima.aop.Target.*(..))
execution(* com.itheima.aop.*.*(..))
execution(* com.itheima.aop..*.*(..))
execution(* *..*.*(..))
2) Type of notification

Configuration syntax for notifications:

<aop:Notification type method="Method name in facet class pointcut="Tangent expression"></aop:Notification type>

3) Extraction of tangent expression

When multiple enhanced pointcut expressions are the same, the pointcut expression can be extracted. In the enhancement, the pointcut ref attribute is used instead of the pointcut attribute to reference the extracted pointcut expression.

<aop:config>
    <!--quote myAspect of Bean Is a tangent object-->
    <aop:aspect ref="myAspect">
        <aop:pointcut id="myPointcut" expression="execution(* com.itheima.aop.*.*(..))"/>
        <aop:before method="before" pointcut-ref="myPointcut"></aop:before>
    </aop:aspect>
</aop:config>

9.3 key points of knowledge

  • aop weaving configuration
<aop:config>
    <aop:aspect ref="Cut class>
        <aop:before method="Notification method name pointcut="Tangent expression"></aop:before>
    </aop:aspect>
</aop:config>
  • Notification types: pre notification, post notification, surround notification, exception throw notification, and final notification
  • How to write tangent point expression:
execution([Modifier ] Return value type package name.Class name.Method name(parameter))

10. Annotation based AOP development

10.1 getting started

Annotation based aop development steps:

① Create target interface and target class (with internal tangent point)

② Create facet class (with enhancement method inside)

③ Leave the object creation rights of the target class and the aspect class to spring

④ Using annotations to configure weaving relationships in facet classes

⑤ Turn on the automatic agent for component scanning and AOP in the configuration file

⑥ Testing

① Create target interface and target class (with internal tangent point)

public interface TargetInterface {
    public void method();
}

public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}

② Create facet class (with enhancement method inside)

public class MyAspect {
    //Pre enhancement method
    public void before(){
        System.out.println("Pre code enhancement.....");
    }
}

③ Leave the object creation rights of the target class and the aspect class to spring

@Component("target")
public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}
@Component("myAspect")
public class MyAspect {
    public void before(){
        System.out.println("Pre code enhancement.....");
    }
}

④ Using annotations to configure weaving relationships in facet classes

@Component("myAspect")
@Aspect
public class MyAspect {
    @Before("execution(* com.itheima.aop.*.*(..))")
    public void before(){
        System.out.println("Pre code enhancement.....");
    }
}

⑤ Turn on the automatic agent for component scanning and AOP in the configuration file

<!--Component scan-->
<context:component-scan base-package="com.itheima.aop"/>

<!--aop Automatic proxy for-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

⑥ Test code

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    @Autowired
    private TargetInterface target;
    @Test
    public void test1(){
        target.method();
    }
}

⑦ Test results

10.2 annotation configuration AOP details

1) Type of annotation notification

Configuration syntax of notification: @ notification annotation ("pointcut expression")

2) Extraction of tangent expression

Same as xml configuration
Like aop, we can extract Pointcut expressions. The extraction method is to define a method in the cut plane, define the cut point expression on the method with the @ Pointcut annotation, and then refer to it in the enhanced annotation. The details are as follows:

@@Component("myAspect")
@Aspect
public class MyAspect {
    @Before("MyAspect.myPoint()")
    public void before(){
        System.out.println("Pre code enhancement.....");
    }
    @Pointcut("execution(* com.itheima.aop.*.*(..))")
    public void myPoint(){}
}

10.3 key points of knowledge

  • Annotate aop development steps

① Dimension facet classes with @ Aspect

② Annotate notification method with @ notification annotation

③ Configure aop auto proxy in the configuration file: AspectJ AutoProxy/

  • Notification annotation type

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-p9tnj5si-1628760647877)( https://cdn.jsdelivr.net/gh/coderchen1/picture2/img/20210811202242.png )]

11. Basic use of jdbctemplate

11.1 - basic use of jdbctemplate - Overview (understand)

  • JdbcTemplate is an object provided in the spring framework and a simple encapsulation of the original cumbersome Jdbc API objects. The spring framework provides us with many operation template classes. For example: JdbcTemplate and HibernateTemplate for operating relational data, RedisTemplate for operating nosql database, JmsTemplate for operating message queue, etc.

11.2 basic use of jdbctemplate - development steps (understanding)

① Import spring JDBC and spring TX coordinates

② Create database tables and entities

③ Create a JdbcTemplate object

④ Perform database operations

11.3 basic use of jdbctemplate - quick start code implementation (application)

Import spring JDBC and spring TX coordinates

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.itheima</groupId>
  <artifactId>itheima_spring_jdbc</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>itheima_spring_jdbc Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>
  <dependencies>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.32</version>
    </dependency>
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.10</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.2.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.3</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
  </dependencies>
</project>

Create database tables and entities

package com.itheima.domain;

public class Account {

    private String name;
    private double money;

    public String getNa me() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

Create a JdbcTemplate object

Perform database operations

@Test
    //Test the development steps of JdbcTemplate
    public void test1() throws PropertyVetoException {
        //Create data source object
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUser("root");
        dataSource.setPassword("root");

        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        //Set the data source object to know where the database is
        jdbcTemplate.setDataSource(dataSource);
        //Perform operation
        int row = jdbcTemplate.update("insert into account values(?,?)", "tom", 5000);
        System.out.println(row);

    }

11.4 basic use of jdbctemplate spring generates template object analysis (understanding)

  • We can hand over the creation right of the JdbcTemplate to Spring and the creation right of the data source DataSource to Spring, inject the data source DataSource into the JdbcTemplate template object inside the Spring container, and then obtain the JdbcTemplate object through the Spring container to perform the operation.

11.5-JdbcTemplate basically uses spring to generate template object code implementation (application)

The configuration is as follows:

<!--Data source object-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql:///test"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
    </bean>

    <!--jdbc Template object-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

Test code

 @Test
    //Test the JDBC template object generated by Spring
    public void test2() throws PropertyVetoException {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        JdbcTemplate jdbcTemplate = app.getBean(JdbcTemplate.class);
        int row = jdbcTemplate.update("insert into account values(?,?)", "lisi", 5000);
        System.out.println(row);
    }

11.6-JdbcTemplate basically uses spring to generate template object code implementation (extract jdbc.properties) (application)

The connection information of the database is extracted into the external configuration file and separated from the spring configuration file, which is conducive to later maintenance

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root

The configuration file is modified to:

<?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"
       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
">

    <!--load jdbc.properties-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--Data source object-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--jdbc Template object-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

11.7 - basic use of jdbctemplate - common operations - update operations (application)

package com.itheima.test;

import com.itheima.domain.Account;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateCRUDTest {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    
	//Modify update
    @Test
    public void testUpdate(){
        jdbcTemplate.update("update account set money=? where name=?",10000,"tom");
    }
	//delete
    @Test
    public void testDelete(){
        jdbcTemplate.update("delete from account where name=?","tom");
    }

}

11.8-basic use of jdbctemplate - common operations - query operations (application)

package com.itheima.test;

import com.itheima.domain.Account;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateCRUDTest {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    
	//Aggregate query
    @Test
    public void testQueryCount(){
        Long count = jdbcTemplate.queryForObject("select count(*) from account", Long.class);
        System.out.println(count);
    }
	//Query a
    @Test
    public void testQueryOne(){
        Account account = jdbcTemplate.queryForObject("select * from account where name=?", new BeanPropertyRowMapper<Account>(Account.class), "tom");
        System.out.println(account);
    }
	//Query all
    @Test
    public void testQueryAll(){
        List<Account> accountList = jdbcTemplate.query("select * from account", new BeanPropertyRowMapper<Account>(Account.class));
        System.out.println(accountList);
    }

}

11.9 basic use of jdbctemplate - key points of knowledge (understanding, memory)

① Import spring JDBC and spring TX coordinates

② Create database tables and entities

③ Create a JdbcTemplate object

		JdbcTemplate jdbcTemplate = newJdbcTemplate();
	       jdbcTemplate.setDataSource(dataSource);

④ Perform database operations

Update operation:

    jdbcTemplate.update (sql,params)

Query operation:

    jdbcTemplate.query (sql,Mapper,params)

jdbcTemplate.queryForObject(sql,Mapper,params)

12. Declarative transaction control

1. Programming transaction control related objects

1.1 PlatformTransactionManager

The PlatformTransactionManager interface is the transaction manager of spring, which provides our common methods of operating transactions.

be careful:

PlatformTransactionManager is an interface type, and different Dao layer technologies have different implementation classes. For example, when Dao layer technology is JDBC or mybatis: org springframework. jdbc. datasource. DataSourceTransactionManager

When Dao layer technology is Hibernate: org springframework. orm. hibernate5. HibernateTransactionManager

1.2 TransactionDefinition

TransactionDefinition is the transaction definition information object, which contains the following methods:

1.3 transaction isolation level

Setting the isolation level can solve the problems caused by transaction concurrency, such as dirty read, non repeatable read and virtual read.

  • ISOLATION_DEFAULT

  • ISOLATION_READ_UNCOMMITTED

  • ISOLATION_READ_COMMITTED

  • ISOLATION_REPEATABLE_READ

  • ISOLATION_SERIALIZABLE

1.4 transaction communication behavior

  • REQUIRED: if there is no transaction currently, create a new transaction. If there is already a transaction, join it. General selection (default)

  • SUPPORTS: SUPPORTS the current transaction. If there is no transaction, it will be executed in a non transactional manner (no transaction)

  • MANDATORY: use the current transaction. If there is no transaction, an exception will be thrown

  • REQUERS_NEW: create a new transaction. If it is currently in a transaction, suspend the current transaction.

  • NOT_SUPPORTED: perform operations in a non transactional manner. If there is a transaction, suspend the current transaction

  • NEVER: runs in a non transactional manner. If there is a transaction, an exception will be thrown

  • NESTED: if a transaction currently exists, it is executed within a NESTED transaction. If there is no current transaction, perform an operation similar to REQUIRED

  • Timeout: the default value is - 1. There is no timeout limit. If yes, set in seconds

  • Read only: it is recommended to set it as read-only when querying

1.5 TransactionStatus

The TransactionStatus interface provides the specific running status of transactions. The methods are described below.

1.6 key points of knowledge

Three objects of programming transaction control

  • PlatformTransactionManager

  • TransactionDefinition

  • TransactionStatus

2 declarative transaction control based on XML

2.1 what is declarative transaction control

Spring's declarative transaction, as its name implies, is to handle transactions in a declarative manner. The declaration here refers to the declaration in the configuration file, and the declarative transaction in the spring configuration file is used to replace the code transaction.

The role of declarative transactions

  • Transaction management does not invade developed components. Specifically, the business logic object will not realize that it is in the process of transaction management. In fact, it should be the same, because transaction management is a system level service, not a part of business logic. If you want to change the transaction management plan, you only need to reconfigure it in the definition file

  • When transaction management is not required, the transaction management service can be removed by modifying the setting file without changing the code and recompiling, which is extremely convenient for maintenance

Note: the underlying layer of Spring declarative transaction control is AOP.

2.2 implementation of declarative transaction control

Declarative transaction control matters:

  • Who is the cut point?

  • Who is the notice?

  • Configure section?

① Introducing tx namespace

<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/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
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">


② Configure transaction enhancements

<!--Platform transaction manager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!--Transaction enhanced configuration-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

③ Configure transaction AOP weaving

<!--Transactional aop enhance-->
<aop:config>
    <aop:pointcut id="myPointcut" expression="execution(* com.itheima.service.impl.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"></aop:advisor>
</aop:config>

④ Test transaction control transfer business code

@Override
public void transfer(String outMan, String inMan, double money) {
    accountDao.out(outMan,money);
    int i = 1/0;
    accountDao.in(inMan,money);
}

2.3 configuration of transaction parameters of pointcut method

<!--Transaction enhanced configuration-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

Where tx:method represents the configuration of transaction parameters of pointcut method, for example:

<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" timeout="-1" read-only="false"/>
  • Name: tangent point method name

  • Isolation: isolation level of transaction

  • Propagation: propagation behavior of transactions

  • Timeout: timeout

  • Read only: read only

2.4 key points of knowledge

Configuration points of declarative transaction control

  • Platform transaction manager configuration

  • Configuration of transaction notifications

  • Configuration of transaction aop weaving

3 annotation based declarative transaction control

3.1 configuring declarative transaction control using annotations

  1. Write AccoutDao
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public void out(String outMan, double money) {
        jdbcTemplate.update("update account set money=money-? where name=?",money,outMan);
    }
    public void in(String inMan, double money) {
        jdbcTemplate.update("update account set money=money+? where name=?",money,inMan);
    }
}
  1. Write AccoutService
@Service("accountService")
@Transactional
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountDao accountDao;
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    public void transfer(String outMan, String inMan, double money) {
        accountDao.out(outMan,money);
        int i = 1/0;
        accountDao.in(inMan,money);
    }
}
  1. Write ApplicationContext XML configuration file
<!—Omitted before datsSource,jdbcTemplate,Configuration of platform transaction manager-->
<!--Component scan-->
<context:component-scan base-package="com.itheima"/>
<!--Annotation driven transactions-->
<tx:annotation-driven/>

3.2 annotation configuration declarative transaction control resolution

① Use @ Transactional to modify classes or methods that need transaction control. The attributes available for annotation are the same as xml configuration methods, such as isolation level, propagation behavior, etc.

② If annotations are used on a class, all methods under the class are configured with the same set of annotation parameters.

③ In terms of methods, different methods can adopt different transaction parameter configurations.

④ Annotation driven to enable transaction in Xml configuration file < TX: annotation driven / >

3.3 key points of knowledge

Configuration points of annotated declarative transaction control

  • Platform transaction manager configuration (xml mode)

  • Configuration of transaction notification (@ Transactional annotation configuration)

  • Transaction annotation driven configuration TX: annotation driven/

Keywords: Spring

Added by delldeveloper on Sat, 25 Dec 2021 05:26:58 +0200