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 range | explain |
---|---|
singleton | Default, singleton |
prototype | Multiple cases |
request | In the web project, Spring creates a Bean object and stores the object in the request field |
session | In the web project, Spring creates a Bean object and stores the object in the session domain |
global session | In 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
annotation | explain |
---|---|
@Component | Used on classes to instantiate beans |
@Controller | Use to instantiate beans on web tier classes |
@Service | Used on the service layer class to instantiate beans |
@Repository | Used on dao layer classes to instantiate beans |
@Autowired | Use on field for type dependent injection |
@Qualifier | Used in conjunction with @ Autowired for dependency injection by name |
@Resource | Equivalent to @ Autowired+@Qualifier, injected by name |
@Value | Inject common attributes |
@Scope | Label the scope of the Bean |
@PostConstruct | Use to label the method, which is the initialization method of the Bean |
@PreDestroy | Use 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>
annotation | explain |
---|---|
@Configuration | Used to specify that the current class is a Spring configuration class from which annotations will be loaded when creating a container |
@ComponentScan | Used 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 |
@Bean | On a method, annotations store the return value of the method in the Spring container |
@PropertySource | For loading Configuration in the properties file |
@Import | Used 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
- 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); } }
- 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); } }
- 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/