This paper summarizes the relevant knowledge points of Spring, including the advantages of Spring, its framework structure, the core idea, and the idea of IoC and AOP are manually implemented to enhance the understanding of the core idea of Spring. After the implementation of Spring IoC, AOP and characteristics are introduced, and compared to the source code to understand its implementation ideas.
- Article content output source: Pull hook education Java high salary training camp;
Spring advantage
-
Easy to decouple and simplify development
[Note: IoC(reduces component coupling), DI(reduces complexity of business object substitution)]
-
AOP programming ideas
[Note: Centralized management of common tasks makes the code more reusable]
-
Support for declarative transactions
[note: @ Transaction]
-
Lightweight framework, low code intrusion, you can freely choose some components of the framework
-
Easy integration of various excellent frameworks
Spring Core Structure
- Spring Core Container: The Core part of the Spring framework is the Container, which manages Bean creation (IoC), configuration (DI), and management (Context). All Spring modules are built on top of the Core Container.
- Aspect Oriented Programming (AOP) : The foundation of aspect development in Spring application systems, code decoupling, enhanced reuse.
- Data Access: Spring’s JDBC and DAO modules encapsulate a lot of boilerplate code, making database code concise and avoiding problems caused by database resource release failures. It consists of MODULES such as JDBC, Transactions (supported by the AOP module), ORM, OXM and JMS.
- Web: Provides the SpringMVC framework for Web applications, as well as a variety of remote invocation schemes for building interactions with other applications. The SpringMVC framework improves the level of loose coupling of applications at the Web layer.
- Test To make it easy for developers to Test, Spring provides a Test module dedicated to testing Spring applications. Through this module, Spring provides a series of mock object implementations for writing unit tests using servlets, JNDI, and so on.
core idea
IoC (Inversion of Control)
IoC is a technical idea, and Spring implements it
Inversion of control: Object creation (instantiation, management) to an external environment (Spring framework, IoC container)
Problem solving: Solve coupling problems between objects
Difference between IoC and DI
Dependancy Injection (DI) Dependency Injection
IoC and DI describe the same thing (object instantiation and dependency maintenance), but from different perspectives
IoC: From the object’s point of view, object instantiation and its management are handed over to the container
DI: From the perspective of the container, the container will inject other objects that the object depends on
Aspect Oriented Programming (AOP) is Aspect oriented Programming
OOP and AOP
OOP is a vertical inheritance system (three characteristics: encapsulation, inheritance, and polymorphism)
AOP extracts horizontal logic code, separates business logic and crosscutting logic, and decouples them in order to solve the vertical duplication problem
AOP problem solving
Solve vertical duplication problem, extract horizontal logic code, separate business logic and crosscutting logic, decouple
Manual implementation of IoC and AOP
IoC and DI implementation
- Define beans.xml, which defines:
- A fully qualified class name and the ID of the object to be created
- The name of the object and its dependent object ID are injected through the Set method of the corresponding class
- Defines a BeanFactory, reads parsed XML, instantiates objects through reflection, manages them uniformly, and provides interface methods for getting objects externally
AOP transaction management
- Bind Connection to the current thread and manually control JDBC Connection transactions (turn off auto-commit transactions)
- Create an agent factory class for transaction enhancement to the agent class
- Method calls are made using proxy class objects instead of objects
Spring IoC application
IoC implementation and corresponding start method
-
Pure XML implementation (bean information definitions are all configured in XML)
// The JavaSE application starts ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); // Or read configuration files in absolute path (not recommended) ApplicationContext applicationContext = new FileSystemXmlApplicationContext("c:/beans.xml"); / / JavaWeb application /** Configure the ContextLoaderListener class (web.xml) listener mechanism to load XML */ Copy the code
<web-app> <display-name>Archetype Created Web Application</display-name> <! -- Configure the Spring IOC container configuration file --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <! Start Spring's IOC container with a listener <listener> <listenerclass>org.springframework.web.context.ContextLoaderListener</listenerclass> </listener> </web-app> Copy the code
-
XML + annotations (Some beans are defined in XML, some beans are defined in annotations)
Consistent with the pure XML implementation
-
Pure annotations (all beans are defined with annotations)
// The JavaSE application starts ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Spring.class); / / JavaWeb application /** Configure the ContextLoaderListener class (web.xml) listener mechanism to load the annotation configuration class */ Copy the code
<web-app> <display-name>Archetype Created Web Application</display-name> <! Tell ContextloaderListener to know that we are using annotations to start the IOC container --> <context-param> <param-name>contextClass</param-name> <paramvalue>org.springframework.web.context.support.AnnotationConfigWebAppli cationContext</param-value> </context-param> <! -- Configure the fully qualified class name of the startup class --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>com.lagou.edu.SpringConfig</param-value> </context-param> <! Start Spring's IOC container with a listener <listener> <listenerclass>org.springframework.web.context.ContextLoaderListener</listenerclass> </listener> </web-app> Copy the code
BeanFactory is different from ApplicationContext
BeanFactory is the top interface of the IoC container in the Spring framework. It is used to define basic functions and specifications. ApplicationContext is one of its subinterfaces. So the ApplicationContext has all the functionality provided by the BeanFactory.
ApplicationContext is a high-level interface to the container that has more functionality than BeanFactory, such as internationalization support and resource access (XML, Java configuration classes), and so on
Three ways to instantiate beans
-
Use a no-parameter constructor
<! -- Configure service object --> <bean id="userService" class="com.lagou.service.impl.TransferServiceImpl"> </bean> Copy the code
-
Create using static methods
<! Static method to create object configuration --> <bean id="userService" class="com.lagou.factory.BeanFactory" factory-method="getTransferService"></bean> Copy the code
-
Create using the instantiation method
<! Create object with instance method --> <bean id="beanFactory" class="com.lagou.factory.instancemethod.BeanFactory"></bean> <bean id="transferService" factory-bean="beanFactory" factory-method="getTransferService"></bean> Copy the code
The scope and life cycle of the Bean
-
Singleton (singleton pattern)
The singleton pattern has the same bean object life cycle as the container
-
Prototype (Multiple examples)
The Spring framework is only responsible for creating, not destroying, multi-instance bean objects
Attributes of Bean tags in Xml schema
- Id: The unique identity of the bean
- Class: Fully qualified class name to create the Bean object
- Name: Give the bean one or more names
- Factory-bean: Specifies the unique identity of the factory bean that created the current bean object (when this property is specified, the class property is invalid)
- Factory-method: Specifies the factory method to create the current object
- Note: When used with factory-bean, the class attribute is invalid. When used with the class attribute, the method must be static
- Scope: Bean scope, default singleton
- Init-method: specifies the bean object initialization method to be called after the bean is assembled. It must bea no-parameter method.
- Destory-method: specifies the bean object destruction method, to be executed before the bean is destroyed. This only works if scope is singleton (because the Spring framework is only responsible for creation in multi-case mode)
DI XML configuration for dependency injection
-
Dependency injection classification
-
Sorted by way of injection
- Constructor injection
- Note: When there is no no-parameter construct, you must provide configuration parameters that match the number of construct parameters and data types
- Assign the constructor with the tag <constructor-arg> with the following attributes:
- Name: Indicates the name of the parameter
- Index: the index specified in the corresponding constructor
- Value: Specifies the basic type or String type data
- Ref: Specifies data of another Bean type and the value is the id of the Bean
- Set method injection
- Use the tag <property> corresponding to the set method, the tag attributes are as follows:
- Name: the name of the set method called during injection
- Value: Specifies the basic type or String type data
- Ref: Specifies data of another Bean type and the value is the id of the Bean
- Use the tag <property> corresponding to the set method, the tag attributes are as follows:
- Constructor injection
-
Sorted by injected data type
-
Basic type, String
-
Complex types [Array, List, Set, Map, Properties]
Example (using set method injection as an example, constructor injection as well) :
<! -- Array --> <property name="myArray"> <array> <value>array1</value> <value>array2</value> </array> </property> <! -- List --> <property name="myArray"> <list> <value>list1</value> <value>list2</value> </list> </property> <! -- Set --> <property name="mySet"> <set> <value>set1</value> <value>set2</value> </set> </property> <! -- Map --> <property name="myMap"> <map> <entry key="key1" value="value1"/> <entry key="key2" value="value2"/> </map> </property> <! -- Properties --> <property name="myProperties"> <map> <prop key="key1" value="value1"/> <prop key="key2" value="value2"/> </map> </property> Copy the code
In the collection data injection of List structure, the array, List, and set tags are common. In addition, the value tag of the annotation value can be directly written, or an object can be configured with the bean tag, or a ref tag can be used to reference a unique identifier of the bean that has been matched. In the collection data injection of the Map structure, the Map label uses the Entry subtag to implement data injection. The Entry tag can specify the data stored in the Map with key and value attributes. Use the value-ref attribute to specify a reference to the configured bean. You can also use the REF tag in the ENTRY tag, but not the bean tag. A ref or bean tag cannot be used to refer to an object in the property tag
-
Other Bean types
-
-
Annotations correspond to XML tags
In the COMBINATION of XML and annotations pattern, beans in third-party JARS are usually defined in XML and bean definitions developed by yourself use annotations
-
configuration
- The @configuration annotation corresponds to beans.xml
- @componentScan annotation, instead of
- @propertysource, introducing an external property profile
- @import introduces additional configuration classes
- @value Assigns a Value to a variable, either directly or using ${} to read information from the resource configuration file
- The @bean adds the method return object to the SpringIoC container
-
IoC
XML form Corresponding annotation form The < bean > tag @Component(“accountDao”), annotation The bean ID attribute content added to the class is configured directly after the annotation. If not, the bean ID is defined as lowercase by default.
In addition, for hierarchical code development to provide @Componenet three aliases @Controller, @Service, @Repository are respectively used to control layer class, Service layer class, DAO layer class bean definition, the usage of these four annotations is exactly the same, just for a clearer distinctionThe scope attribute @scope (“prototype”), default singleton, annotation added to class The init-method property of the tag @postconstruct, the annotation is placed on the method that is called after initialization Destory – method attribute @predeStory, annotation to the method that was called before destruction -
DI
- @Autowired
- Injection by type. If there are multiple bean values, use it with @Qualifier(name=””)
- @Resource
- J2EE provide @ Resource in 11 of the Jdk has been removed, javax.mail to import package. The annotation. The Resource
- Injection rules:
- If both name and Type are specified, a unique matching bean is found from the Spring context and assembled, failing which an exception is thrown.
- If name is specified, the bean whose name (ID) matches is searched from the context for assembly, and an exception is thrown if no bean is found.
- If type is specified, an exception is thrown if a unique bean similar to a match is found from the context and assembled.
- If neither name nor type is specified, byName is automatically used for assembly.
- @Autowired
Spring IoC common features
Lazy-init lazy loading
- Lazy loading off (default) : The default behavior of the ApplicationContext container is to instantiate all Singleton beans ahead of time when the server is started
- Lazy loading enabled: Beans are not instantiated in advance when ApplicationContext is started, but when the bean is first requested from the container via getBean.
- Set lazy-init=”true” in
to control individual beans
- Set default-lazy-init=”true” at
to control all beans under this container
- Set lazy-init=”true” in
Function:
- Enabling delayed loading can improve container startup and operation performance to a certain extent
- Lazy loading is set up for infrequently used beans so that they can be loaded only when they are used infrequently and do not need to hog resources from the beginning
FactoryBean and the BeanFactory
-
BeanFactory interface: The top-level interface of the container that defines some of the basic behavior of the container
-
The FactoryBean interface: Uses it to customize beans, static and instantiated methods that act like bean-created methods
Method of use
-
Create a Factory class for your Bean, implement the FactoryBean interface, and override getObject(), getObjectType(), and isSingleton().
-
Configure the Factory class in XML
-
Container initialization automatically instantiates the Factory object and calls its getObject() to manage it
Note: If you need a Factory object, you can get the &${id} object in the container
<bean id="testBean" class="com.test.TestBeanFactory"></bean> <! GetBean ("&testBean") getBean("&testBean") getBean("&testBean") getBean("&testBean") getBean("&testBean") Copy the code
-
Rear processor
Spring provides extended interfaces for two types of post-processing beans
-
BeanPostProcessor: Called after the Bean object is instantiated and assembled
This interface provides two methods:
- Before postProcessBeforeInitialization: Bean initialization method
- After postProcessAfterInitialization: Bean initialization method
-
BeanFactoryPostProcessor: Called after the BeanFactory is initialized (before the bean is instantiated and has just been parsed into a BeanDefinition object)
This interface provides a method and parameters for ConfigurableListableBeanFactory, the parameter types defines some methods, one method called getBeanDefinition method, we can according to this method, Find the BeanDefinition object where we defined the bean. We can then modify the defined properties.
**BeanDefinition object: ** The bean label we defined in XML, Spring parses the bean label into a JavaBean, which is the BeanDefinition
Spring IoC source code analysis
The Spring IoC container inheritance architecture
! [](img/Spring IoC container inheritance system.jpg)
Bean lifecycle critical timing points
Bean object creation of several key timing code level calls in AbstractApplicationContext refresh methods of a class
The key point | Trigger code |
---|---|
The constructor | refresh#finishBeanFactoryInitialization(beanFactory)(beanFactory) |
Spring BeanFactoryPostProcessor initialization | refresh#invokeBeanFactoryPostProcessors(beanFactory) |
BeanFactoryPostProcessor method call | refresh#invokeBeanFactoryPostProcessors(beanFactory) |
BeanPostProcessor initialization | registerBeanPostProcessors(beanFactory) |
BeanPostProcessor method call | refresh#finishBeanFactoryInitialization(beanFactory) |
The source code is as follows:
public void refresh(a) throws BeansException, IllegalStateException {
// Object lock lock
synchronized (this.startupShutdownMonitor) {
/* Prepare this context for refreshing. Preprocessing before the refresh represents the things that need to be done before the actual refresh operation: setting the start time of the Spring container, turning on the active state, revoking the closed state and verifying some mandatory attributes in the environment information, etc. */
prepareRefresh();
/* Tell the subclass to refresh the internal bean factory. To obtain the BeanFactory; The default implementation is DefaultListableBeanFactory load BeanDefition and register to BeanDefitionRegistry * /
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
/* Prepare the bean factory for use in this context. BeanFactory prepares the bean factory for use in this context
prepareBeanFactory(beanFactory);
try {
/* Allows post-processing of the bean factory in context subclasses. BeanFactory Allows post-processing of the bean factory in context subclasses */
postProcessBeanFactory(beanFactory);
/* Invoke factory processors registered as beans in the context. Instantiate the Bean that implements the BeanFactoryPostProcessor interface and call the interface method */
invokeBeanFactoryPostProcessors(beanFactory);
/* Register bean processors that intercept bean creation. Register the BeanPostProcessor (the Bean's post-processor) to execute */ before and after creating the Bean
registerBeanPostProcessors(beanFactory);
/* Initialize message source for this context. Initialize the MessageSource component (do internationalization; Message binding, message parsing); * /
initMessageSource();
/* Initialize event multicaster for this context. Initialize the event dispatcher */
initApplicationEventMulticaster();
/* Initialize other special beans in specific context subclasses. Subclasses override this method to customize the logic when the container is refreshed; Create Tomcat, Jetty and other WEB servers */
onRefresh();
/* Check for listener beans and register them. Registers application listeners. Is to register a listener bean */ that implements the ApplicationListener interface
registerListeners();
/* Instantiate all remaining (non-lazy-init) singletons. Initialize all remaining non-lazy-loaded singleton bean instantiations create non-lazy-loaded singleton bean instances (with no properties set) fill property initializer method calls (e.g. AfterPropertiesSet, init-method) Call BeanPostProcessor (post-processor) to post-process the instance bean */
finishBeanFactoryInitialization(beanFactory);
/* Last step: publish corresponding event. The context is refreshed. The main thing is to call the LifecycleProcessor's onRefresh() method and publish events (ContextRefreshedEvent) */
finishRefresh();
}catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: "+ ex); }// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...resetCommonCaches(); }}Copy the code
BeanFactory creation process
Get the BeanFactory subprocess
BeanDefinition loads the parsing and registration subprocesses
- Resource localization: The process of encapsulating XML files into Resource objects
- BeanDefinition loading: The user-defined Javabeans are represented as data structures inside the IoC container, and the data structures inside the container are beanDefinitions.
- Register the BeanDefinition into the IoC container
Bean creation process
Note: Refer to the IoC cycle dependent sequence diagram
Principle of lazy-Inti lazy loading mechanism
public void preInstantiateSingletons(a) throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// The names of all beans
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// Triggers the initialization of all non-lazy-loaded singleton beans, the main step being getBean
for (String beanName : beanNames) {
// Merge the parent BeanDefinition object
// map.get(beanName)
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if(! bd.isAbstract() && bd.isSingleton() && ! bd.isLazyInit()) {if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// If it is a FactoryBean, add &
if (bean instanceof FactoryBean) {
finalFactoryBean<? > factory = (FactoryBean<? >) bean;boolean isEagerInit;
if(System.getSecurityManager() ! =null && factory instanceofSmartFactoryBean) { isEagerInit = AccessController .doPrivileged((PrivilegedAction<Boolean>)((SmartFactoryBean<? >) factory)::isEagerInit, getAccessControlContext()); }else {
isEagerInit = (factory instanceofSmartFactoryBean && ((SmartFactoryBean<? >) factory).isEagerInit()); }if(isEagerInit) { getBean(beanName); }}}else {
// Instantiate the current beangetBean(beanName); }}}// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if(System.getSecurityManager() ! =null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}else{ smartSingleton.afterSingletonsInstantiated(); }}}}Copy the code
Such as the source code:
- For beans decorated as lazy-init, the Spring container does not init and dependency injection during the initialization phase, but only when the getBean is first initialized and dependency injected
- For non-lazy-loaded beans, the getBean is fetched from the cache because the bean has already been initialized and cached during container initialization
Spring IoC loop dependency issues
-
Singleton bean constructor parameter loop dependency (unresolvable)
-
Prototype bean loop dependency
Spring will error handle the initialization of the prototype bean either through the constructor parameter cyclic dependency or through the setXxx method.
-
Singleton beans are loop dependent via setXxx or @autowired
Spring’s theory of cyclic dependency is based on Java reference passing. When a reference to an object is obtained, the object’s properties can be set later, but the constructor must be set before the reference is obtained
Spring AOP applications
Relevant concepts
- JoinPoint (joinPoint) : a candidate point when a method starts, ends, runs normally, and is abnormal
- PointCut: Specify the specific methods that AOP affects and describe the methods of interest
- Advice: A method used in the aspect class to provide enhancements. It also represents the type of Advice, classified as:Pre notification, post notification, exception notification, final notification, surround notification
- Crosscutting logic
- Bearing point
- Target: the proxied object
- Proxy: Proxy object
- Weaving: The process of applying enhancements to target objects to create new proxy objects. Spring uses dynamic weaving, while AspectJ uses compile-time weaving and class-load weaving.
- Aspect: The Aspect that enhanced code focuses on. [Example: TransactionManage class]
- Aspect: The concept of section is a synthesis of the above concepts
- Aspect Aspect = pointcut + enhancement = pointcut (locking method) + azimuth point (special timing in locking method) + crosscutting logic
AOP proxy selection in Spring
-
Spring implements AOP ideas using dynamic proxy techniques
-
By default
Select a JDK dynamic proxy if the proxy class implements an interface
Otherwise, CGLIB dynamic proxy is selected
-
The CGLIB dynamic proxy can be forcibly configured
Spring AOP implementation
1. The XML schema
- Introduction of depend on
- Leave the beans to Spring to manage
- Configuration < aop: config >
- Configuration aspect < AOP :aspect>
- Configure notification enhancement in the section, one is azimuth, the other is cut point
Points to note:
-
Pointcut expression
A string that follows a particular syntactic structure and is used to enhance syntactic join points.
/ / sample
// Fully qualified method name access modifier return value package name. Package name. Package Name. Class Name. Method name (parameter list)
// Full matching mode:
public void com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account) // Access modifiers can be omitted
void com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account)
// The return value can be *, indicating any return value
* com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account)
// The package name can be used to represent any package, but there are several levels of packages, and several must be written*... TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account)// Package name can be used.. Represents the current package and its subpackages
* ..TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account)
// The class name and method name can be used to indicate any class or method
* ...(com.lagou.pojo.Account)
// Parameter list, can use the specific type basic type directly write type name: int
// The reference type must be written with the fully qualified class name: java.lang.string
// The parameter list can use * to indicate any parameter type, but must have parameters* *.. *. * (*)// Parameter list can be used with.. , indicates that the parameter is optional. Some parameters can be of any type* *.. *. * (..)// Full wildcard mode:* *.. *. * (..)Copy the code
-
Change the proxy configuration
-
Use the < AOP :config> tag for configuration
<aop:config proxy-target-class="true"> Copy the code
-
Use the < AOP: Aspectj-AutoProxy > tag for configuration
<! This tag is required when configuring AOP based on XML and annotations. It indicates that Spring has enabled annotation configuration AOP support. <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectjautoproxy> Copy the code
-
-
Five types of notification
-
Pre-notification: Execute before the pointcut method executes
<aop:before>
-
Post-advice: Execute after the pointcut method executes normally
<aop:after-returning>
-
Exception notification: Execute after the pointcut method execution generates an exception
<aop:after-throwing>
-
Final notification: After the pointcut method executes, the pointcut method executes before it returns (executes regardless of exceptions, finally)
<aop:after>
-
Circular notification: In particular, the ProceedingJoinPoint interface and its implementation classes are used to manually trigger the invocation of pointcut methods
-
2. XML + annotation schema
-
Turn on Spring support for annotation AOP in XML
<! Enable Spring support for annotation AOP --> <aop:aspectj-autoproxy/> Copy the code
-
The sample
/** * simulate logging */ @Component @Aspect public class LogUtil { /** * We already use generic pointcut expressions in XML for multiple facets, so how do we use them in annotations? * Step 1: Write a method * Step 2: Use it in a method@PointcutAnnotation * Step 3: Provide a pointcut expression for the annotation's value property * detail: * 1. When referring to pointcut expressions, it must be the method name +(), such as "pointcut()". * 2. In the current section, can directly write method name. Use in other facets must be fully qualified method names. * / @Pointcut("execution(* com.lagou.service.impl.*.*(..) )") public void pointcut(a){} @Before("pointcut()") public void beforePrintLog(JoinPoint jp){ Object[] args = jp.getArgs(); System.out.println("Pre-notification: beforePrintLog, parameter is:"+Arrays.toString(args)); } @AfterReturning(value = "pointcut()",returning = "rtValue") public void afterReturningPrintLog(Object rtValue){ System.out.println("AfterReturningPrintLog, return value:+rtValue); } @AfterThrowing(value = "pointcut()",throwing = "e") public void afterThrowingPrintLog(Throwable e){ System.out.println("Exception notification: afterThrowingPrintLog, exception is:"+e); } @After("pointcut()") public void afterPrintLog(a){ System.out.println("Final notification: afterPrintLog"); } /** * surround notification *@param pjp * @return* / @Around("pointcut()") public Object aroundPrintLog(ProceedingJoinPoint pjp){ // Define the return value Object rtValue = null; try{ // Pre-notification System.out.println("Advance notice"); //1. Obtain parameters Object[] args = pjp.getArgs(); //2. Execute the pointcut method rtValue = pjp.proceed(args); // post notification System.out.println("Post notification"); }catch (Throwable t){ // Exception notification System.out.println("Exception notification"); t.printStackTrace(); }finally { // Final notification System.out.println("Final notice"); } returnrtValue; }}Copy the code
3. Annotation mode
- Turn on Spring’s support for annotation AOP by adding @enableAspectJAutoProxy to the configuration class
Spring’s support for declarative transactions
** Programmatic transactions: ** A transaction control mechanism that adds transaction control code to the business code is called programmatic transactions
** Declarative transactions: ** Control of a transaction through XML or annotation configuration is called declarative transactions
Four features of transactions
-
** Atomicity: ** Atomicity refers to the fact that a transaction is an indivisible unit of work in which all or none of the operations occur.
Described from an operational point of view
-
Consistency: a transaction must change the database from one consistent state to another.
Describe it in terms of data
-
** Isolation: The Isolation of ** transactions refers to the transactions opened by the database for each user when multiple users concurrently access the database. Each transaction cannot be disturbed by the operation data of other transactions, and multiple concurrent transactions must be isolated from each other.
-
** Durability: ** Durability means that once a transaction is committed, its changes to the data in the database are permanent and subsequent failure of the database should not affect it.
Transaction isolation level
Question:
- Dirty read: a transaction in one thread reads uncommitted data in another thread.
- Non-repeatable read: a transaction in one thread reads an update that has been committed by another thread.
- Virtual read: a transaction in one thread reads an INSERT or DELETE that has been committed by another thread.
There are four database isolation levels:
-
Serializable: Avoids dirty read, unrepeatable read, and virtual read. (serialization) highest
-
Repeatable Read: can avoid dirty read and unrepeatable read. (Phantom reading may occur) Second
This mechanism locks the rows to be updated
-
Read COMMITTED: Prevents dirty reads from happening. Unrepeatable reads and phantom reads must occur. The third
-
Read Uncommitted: Indicates the lowest level. None of the above can be guaranteed. (Read unsubmitted) minimum
Note: As levels go up, efficiency goes down
MySQL’s default isolation level is: REPEATABLE READ
Transaction propagation behavior
Always use the first two (bold)
PROPAGATION_REQUIRED | If there is no transaction, create a new one. If there is already one, join it. This is the most common choice. |
---|---|
PROPAGATION_SUPPORTS | Current transactions are supported, and non-transactionally executed if there are none. |
PROPAGATION_MANDATORY | Use the current transaction and throw an exception if there is no transaction currently. |
PROPAGATION_REQUIRES_NEW | Create a new transaction and suspend the current transaction if one exists. |
PROPAGATION_NOT_SUPPORTED | Performs the operation nontransactionally, suspending the current transaction if one exists. |
PROPAGATION_NEVER | Executes nontransactionally, throwing an exception if a transaction currently exists. |
PROPAGATION_NESTED | If a transaction currently exists, it is executed within a nested transaction. If there are no transactions currently, an operation similar to PROPAGATION_REQUIRED is performed. |
Spring declarative transaction configuration
Note: Similar to the AOP configuration, configure <tx:advice>
Turn on Spring support for annotation transactions
< tx: annotation – driven transactionmanager = “transactionmanager” / > or @ EnableTransactionManagement
Spring AOP source code analysis
AOP source code analyzes class method invocation relationships
Org. Springframework. Beans. Factory. Support. AbstractAutowireCapableBeanFactory# initializeBean calls org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization call . Org. Springframework. Aop framework. Autoproxy. AbstractAutoProxyCreator# postProcessAfterInitialization (rear AbstractAutoPro processor XyCreator complete bean proxy object creation) call org. Springframework. Aop) framework. Autoproxy. AbstractAutoProxyCreator# wrapIfNecessary calls . Org. Springframework. Aop framework. Autoproxy. AbstractAutoProxyCreator# createProxy (in this step the delegate object of aop enhancements and gm to intercept a merger, Eventually to proxy objects) call org. Springframework. Aop) framework. DefaultAopProxyFactory# createAopProxy calls org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader )Copy the code
Spring declarative transaction control
@EnableTransactionManagementannotations1) by@importIntroduced its selectImports TransactionManagementConfigurationSelector class method to import the other two categories: AutoProxyRegistrar and ProxyTransactionManagementConfiguration2Via registerBeanDefinitions, the AutoProxyRegistrar class analysis method, InfrastructureAdvisorAutoProxyCreator, introduced by AopConfigUtils. RegisterAutoProxyCreatorIfNecessary (registry), It inherits AbstractautoXyCreator, which is a postprocessor class3) ProxyTransactionManagementConfiguration is an added@ConfigurationThe configuration class for annotations (registration bean) registers the transaction enhancer (injection property parser, transaction interceptor) property parser: AnnotationTransactionAttributeSource, internal hold a parser collection Set < TransactionAnnotationParser > annotationParsers; Specific use SpringTransactionAnnotationParser parser to parse@TransactionalTransaction interceptor: TransactionInterceptor implements the MethodInterceptor interface, which is a generic interceptor that merges with aop enhancements before producing proxy objects. The invokeWithinTransaction method, which ultimately affects the broker object TransactionInterceptor, triggers the original business logic call (enhanced transaction)Copy the code