First up: Today we are going to talk about agents in Java. Let’s talk about the background of the story:

Xiao Ming want to buy a certain brand of perfume for his girlfriend, but there is no supply of goods sold in the domestic, personally go to France and struggle, and the little red now are playing in France, she was a good friend, xiao Ming can help xiao Ming to buy this brand of perfume, so xiao Ming will find little red, promised to give her more 5% of hard, little red said yes, Xiao Ming succeeded in buying French perfume in China. Then Xiao Hong started a crazy daigou mode, earning a lot of fees.

In the story, Xiao Ming is a customer who asks Xiao Hong to help him buy perfume. Xiao Hong becomes an agent, while the perfume provider is a real person who can sell perfume. Xiao Ming buys French perfume through the agent Xiao Hong, which is an example of purchasing on behalf of others. I drew a picture to help understand the whole structure of the story.

This story is the most typical agent mode, daigou buys goods from the supplier and returns them to the caller, namely Xiao Ming who needs the agent.

Agents can be divided into static agents and dynamic agents:

Static agent

  • Advantages: Simple code structure, easy to implement
  • Disadvantages: Cannot adapt to all agent scenarios. If new requirements arise, you need to modify the agent class, which does not comply with the open and close principles of software engineering

Xiao Hong is now only the agent of perfume, if Xiao Ming needs to find Xiao Hong to buy French red wine, then Xiao Hong needs to act as the agent of French red wine, but the static agent to expand the function of the agent must modify the logic of Xiao Hong, which will make xiao Hong internal code more and more bloated, later will be analyzed in detail.

A dynamic proxy

  • Advantages: Dynamic adaptation to specific agent scenarios, good scalability, in line with the open and closed principles of software engineering
  • Disadvantages: Dynamic proxies require the use of reflection and dynamic bytecode generation, resulting in slightly worse performance than static proxies, but these disadvantages are almost negligible compared to the advantages

If Xiao Ming needs to find a small red wine agent, we do not need to modify the agent class of small red internal logic, just need to pay attention to the extension of the function point: agent red wine, instantiation of the new class, through some transformation can let xiao Hong is able to agent perfume can also agent red wine.

This article will try to get you as close to understanding all the important points in Java proxies as possible:

  1. Learn the proxy pattern (code to implement the story, explaining the class structure characteristics of the proxy pattern)
  2. Compare the similarities and differences between static and dynamic proxies
  3. Two dynamic Proxy implementations common in Java (JDK Proxy and Cglib)
  4. Application of Dynamic Proxy (Spring AOP)

The proxy pattern

(1) We define an interface for selling perfume, define the method of selling perfume and input the price of perfume.

public interface SellPerfume {
    void sellPerfume(double price);
}
Copy the code

(2) Define Chanel perfume provider and implement interface.

public class ChanelFactory implements SellPerfume {
    @Override
    public void sellPerfume(double price) {
        System.out.println("Successful purchase of Chanel perfume, price:" + price + "Yuan"); }}Copy the code

(3) Define xiaohong’s agent class. She needs to buy chanel perfume on behalf of others, so she is the agent object of Chanel perfume provider. The interface is also realized, and the reference to the target object (Chanel provider) is saved internally, and the access of other objects to the target object is controlled.

public class XiaoHongSellProxy implements SellPerfume {
	private SellPerfume sellPerfumeFactory;
    public XiaoHongSellProxy(SellPerfume sellPerfumeFactory) {
        this.sellPerfumeFactory = sellPerfumeFactory;
    }
    @Override
    public void sellPerfume(double price) {
        doSomethingBeforeSell(); // Pre-enhanced
        sellPerfumeFactory.sellPerfume(price);
        doSomethingAfterSell(); // post-enhance
    }
    private void doSomethingBeforeSell(a) {
        System.out.println("Little Red agent's extra operations before buying perfume...");
    }
    private void doSomethingAfterSell(a) {
        System.out.println("Red agent buys perfume after additional operation..."); }}Copy the code

(4) Xiao Ming is a demander, he needs to buy perfume, only through Xiao Hong to buy, so he went to Xiao Hong to buy perfume in 1999.

public class XiaoMing {
    public static void main(String[] args) {
        ChanelFactory factory = new ChanelFactory();
        XiaoHongSellProxy proxy = new XiaoHongSellProxy(factory);
        proxy.sellPerfume(1999.99); }}Copy the code

Let’s take a look at the operation results. Xiao Hong can perform additional operations before selling perfume to Xiao Ming. If the honest daigou will give a discount and free delivery, while if the dishonest daigou will add a handling fee and the sale will not be returned…

Let’s take a look at the relationship structure of the above four classes. It can be found that both Xiao Hong and Chanel providers have realized the interface of selling perfume, while Xiao Hong has added a reference to the provider to invoke the perfume selling function of the provider.

To implement the proxy mode, you need to follow the following steps:

  • Define public interfaces for real objects and proxy objects (perfume selling interface)
  • The proxy object holds a reference to the real target object internally (small red reference provider)
  • Visitors can only access real target objects through proxy objects, not directly (Xiao Ming can only buy perfume through Xiao Hong, not directly from Chanel provider)

Proxy mode is easy to produce wrong thinking one place: proxy objects is not really an object of the services they offer, it’s just for visitors to access the target object is an intermediary, the real service or the target object, and the role of the proxy object is to provide the service before and after the target object to perform additional logic.

From the story, Xiao Hong is not really selling perfume, selling perfume or Chanel provider, and Xiao Hong is just in let Chanel sell perfume before and after the implementation of some of their own additional operations.

After the code implementation of this proxy pattern, we will systematically learn how it is defined and what specifications need to be looked at to implement it.

Definition of proxy pattern: Provide a proxy object to a target object, contain the target object, and control access to it.

The purpose of the proxy pattern:

  • Isolation of proxy objects enables additional business logic to be added before and after the target object is accessed for enhanced functionality.
  • Using proxy objects to access target objects can prevent the system from accessing target objects incorrectly and causing unpredictable consequences

Static versus dynamic proxies

Are you wondering, like me, why there are static and dynamic proxies? What’s the difference between them?

Obviously, everyone has this question, so let’s look at some of the similarities:

  • Can implement the proxy mode.
  • Both the proxy object and the target object need to implement a common interface for both static and dynamic proxies

The point is, of course, that the dynamic proxy is an improvement on the static proxy, greatly improving the maintainability and extensibility of the program. Let me list the differences between the two and explain in detail why static proxies don’t have these two features:

  • Dynamic proxy generates proxy objects dynamically at runtime without Java source files. It directly generates bytecode files to instantiate proxy objects. The static proxy object, on the other hand, has already written the Java file when the program is compiled. Simply new a proxy object.
  • Dynamic proxies are more robust than static proxies and are more maintainability and extensibility friendly to applications

Now, proxy objects little red agent have been able to buy the perfume, but one day, little red another friend can come, he wanted to buy the most pure French red wine, no such domestic purchase channels, small red just also in France, so he just want to find a small HongBang he bought a red wine, and xiao Ming to find this little red is a truth, is to make the little red agent.

But the problem is: in the program, Xiao Hong can only buy perfume as an agent, if you want to buy wine as an agent, how to do it?

  • Create an interface to sell wine

  • Both the wine seller and the agent xiao Hong need to implement this interface

  • Xiao He visits Xiao Hong and asks her to sell him red wine

OK, that’s it, I’m not going to write the code again, so let’s talk about, are there any flaws in this implementation for this new scenario?

We have to mention the open close principle in software engineering

Open closed principle: when writing a program, all objects in the software should be open for extension and closed for modification

Static proxies violate the open and close principle because they become increasingly large and difficult to maintain due to new requirements that require modifying the proxy class to implement new interfaces and methods.

Although said that currently the proxy class is only realized the two interfaces, if small red in the future is not just a * * agent selling the red wine, also need the agent to sell the tickets, buying Japanese sushi…… * * implementation of the interface becomes more and more, the internal structure is becoming more and more complex, whole class appears increasingly bloated, become unmaintainable, after expansion will also be a problem, Any change to any interface will involve the proxy class, which is costly to maintain.

Therefore, in order to improve the extensibility and maintainability of classes and meet the open and closed principle, Java provides dynamic proxy mechanism.

A common dynamic proxy implementation

Dynamic proxy is of course the most important dynamic two words, learning the process of dynamic proxy, the most important is to understand what is dynamic, not to say, immediately open the whole.

Let’s be clear: dynamic proxies solve the problem that when faced with new requirements, there is no need to modify the code of the proxy object, just need to add interfaces and real objects, and call the client to complete the new proxy.

The purpose of this is to meet the open and close principles of software engineering and improve the maintainability and extensibility of classes.

JDK Proxy

JDK Proxy is a dynamic Proxy mechanism provided by the JDK. It involves two core classes, Proxy and InvocationHandler. Let’s learn how to use them first.

Take the story of Xiaohong agent selling perfume as an example, Chanel perfume provider is still the real object, to achieve the SellPerfume interface, here is no longer written, the focus is xiaoHong agent, the agent object here is no longer a person, but an agent factory, there will be many agents. I drew a picture that will make a lot of sense when you look at it:

Xiaoming comes to the agency factory and needs to buy a Chanel perfume on sale in France. Then the factory will ** find an actual agent (dynamic instantiation) ** to allocate to Xiaoming, such as Xiaogong or Xiaohua, so that the agent can fulfill Xiaoming’s needs. The agent factory has an infinite number of agent objects that can be assigned, and the things that each object can delegate can change dynamically based on the program, without modifying the agent factory.

If One day Xiao Ming needs to entertain an agent who can buy wine on behalf of him, the agent factory can still meet his needs. No matter what agent he needs in the future, he can meet it, don’t you think it’s amazing? Let’s learn how to use it.

Let’s take a look at what a UML class diagram structure for a dynamic proxy looks like.

As you can see, this is not much different from static proxies. The only change is to the proxy object, which I have marked: produced by the proxy factory.

Proxy objects are dynamically generated by proxy factories while the program is running. There are no Java source files for proxy objects themselves.

So, we focus on two things:

  • How to implement a proxy factory
  • How do I dynamically generate proxy objects from a proxy factory

First, the proxy factory needs to implement the InvocationHanlder interface and implement its invoke() method.

public class SellProxyFactory implements InvocationHandler {
	/** The real object of the proxy */
    private Object realObject;

    public SellProxyFactory(Object realObject) {
        this.realObject = realObject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        doSomethingBefore();
        Object obj = method.invoke(realObject, args);
        doSomethingAfter();
        return obj;
    }

    private void doSomethingAfter(a) {
        System.out.println("Additional operations after agent execution...");
    }

    private void doSomethingBefore(a) {
        System.out.println("Additional operations prior to agent execution..."); }}Copy the code

The invoke() method takes three arguments:

  • Object proxy: proxy object
  • Method method: Method of actual execution
  • Object[] agrs: The argument list value passed in when the second argument method is called

The invoke() method is a proxy method, which means it is executed when the last client requests the proxy. Now that the proxy factory class is over, let’s look at the second point: how to dynamically generate proxy objects from a proxy factory.

To generate a Proxy object, we need to use the Proxy class, which can help us to generate any Proxy object, providing a static method newProxyInstance.

Proxy.newProxyInstance(ClassLoader loader, Class<? >[] interfaces, InvocationHandler h);Copy the code

When instantiating a proxy object, you pass in three parameters:

  • ClassLoader: a ClassLoader that loads dynamic proxy classes
  • Class
    [] interfaces: Interfaces implemented by the proxy class that can be passed in multiple interfaces
  • InvocationHandler H: specifies the proxy classCall handlerThat is, the proxy factory is found when a method in the interface is calledh, the implementation ofinvoke()methods

We need this method when the client requests the proxy.

public class XiaoMing {
    public static void main(String[] args) {
        ChanelFactory chanelFactory = new ChanelFactory();
        SellProxyFactory sellProxyFactory = new SellProxyFactory(chanelFactory);
        SellPerfume sellPerfume = (SellPerfume) Proxy.newProxyInstance(chanelFactory.getClass().getClassLoader(),
                chanelFactory.getClass().getInterfaces(),
                sellProxyFactory);
        sellPerfume.sellPerfume(1999.99); }}Copy the code

The result of execution is the same as the result of static proxy, but the idea is different, one is static, the other is dynamic. So how do dynamic proxies benefit? Don’t worry, just look down.

Look at the picture below, compared with static agent and rear of the front of enhancement, little little in red words, actually agent factory allocation proxy objects is random, not for a particular object of the agent, so every time the generated proxy object is different, also not sure whether the little red, but can only determine that, This agent can help Xiao Ming buy perfume just like Xiao Hong!

According to the previous storyline, Xiao Hong went to the agent of wine, and Xiao Ming wanted to buy famous French wine, so she went to the agent factory and asked it to assign another person to buy wine for Xiao Ming. The agent factory said: “Of course there is no problem! We are professional! Wait!”

We need to implement two classes: the wine provider class and the wine seller interface.

/** Interface for selling wine */
public interface SellWine {
    void sellWine(double price);
}

/** Wine supplier */
public class RedWineFactory implements SellWine {

    @Override
    public void sellWine(double price) {
        System.out.println("Successfully sold a bottle of wine, price:" + price + "Yuan"); }}Copy the code

Then our Xiaoming can instantiate an agent who can sell wine when he requests an agent factory.

public class XiaoMing {
    public static void main(String[] args) {
        // Instantiate a wine seller
        RedWineFactory redWineFactory = new RedWineFactory();
        // Instantiate the broker factory, passing in a wine seller reference to control access to it
        SellProxyFactory sellProxyFactory = new SellProxyFactory(redWineFactory);
        // Instantiate a proxy object that can sell wine as a proxy
        SellWine sellWineProxy = (SellWine) Proxy.newProxyInstance(redWineFactory.getClass().getClassLoader(),
                redWineFactory.getClass().getInterfaces(),
                sellProxyFactory);
        // Agent selling wine
        sellWineProxy.sellWine(1999.99); }}Copy the code

Looking forward to the implementation result, you will be surprised to find that we can actually sell wine as an agent, but we have not changed the agent factory.

To review our new wine proxy feature, there are two steps:

  • Create a new wine providerSellWineFactoryAnd selling wine interfaceSellWine
  • Instantiate a proxy object on the client side and purchase wine from that proxy object

Think back to the open closed principle: open for extension, closed for modification. Dynamic proxy is to meet this important principle, in the face of functional requirements expansion, only need to pay attention to the extension part, do not need to modify the original system code.

For those interested in further research, focus on the proxy.newProxyinstance () method, which is one of the entire JDK dynamic Proxy takeoff.

With that said, the JDK has come to the end of providing dynamic proxies. Let’s summarize the JDK dynamic proxies:

(1) The use of JDK dynamic proxy

  • The proxy factory needs to be implementedInvocationHandlerInterface that turns to execution when a proxy method is invokedinvoke()methods
  • Used to generate proxy objectsProxyThe object of thenewProxyInstance()Method that returns an object that can be forcefully converted to one of the interfaces passed in, and then implements the proxy by calling the interface method

(2) Features of JDK dynamic proxy

  • The target object enforces the need to implement an interface otherwise JDK dynamic proxies cannot be used

(The following is an extension, which can be skipped if you don’t want to see it)

Proxy.newproxyinstance () is the key to generating dynamic Proxy objects. Let’s take a look at what’s going on inside of proxy.newproxyInstance ().

private static finalClass<? >[] constructorParams ={ InvocationHandler.class };public static Object newProxyInstance(ClassLoader loader, Class
       [] interfaces, InvocationHandler h) {
    // Get the Class object of the proxy ClassClass<? > cl = getProxyClass0(loader, intfs);// Get the display constructor for the proxy object with the argument type InvocationHandler
    finalConstructor<? > cons = cl.getConstructor(constructorParams);// reflection, instantiating the dynamic proxy object through the constructor
    return cons.newInstance(new Object[]{h});
}
Copy the code

We see that line 6 fetches a dynamic proxy object, so how is it generated? And then we look down.

private staticClass<? > getProxyClass0(ClassLoader loader, Class<? >... interfaces) {// Get the proxy Class object from the proxy Class cache
    return proxyClassCache.get(loader, interfaces);
}
Copy the code

The access to the proxyClassCache cache is similar to the map structure. The access to the get() method is based on the Class loader and the interfaces implemented by the real object.

 public V get(K key, P parameter) {
     // Check whether the Class object can be queried based on key and parameter
     // ...
     // Generate a proxy class
     Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
 }
Copy the code

In the get() method, if no Class object is retrieved from the cache, a dynamic Proxy object needs to be instantiated using subKeyFactory, and a ProxyClass contains a ProxyClassFactory inner Class that creates a dynamic ProxyClass. So let’s move on to the apply() method in ProxyClassFactory.

private static final class ProxyClassFactory
    implements BiFunction<ClassLoader.Class<? > [].Class<? >>{
    // Very important, this is the object name prefix we see for dynamic proxies!
	private static final String proxyClassNamePrefix = "$Proxy";

    @Override
    publicClass<? > apply(ClassLoader loader, Class<? >[] interfaces) { Map<Class<? >, Boolean> interfaceSet =new IdentityHashMap<>(interfaces.length);
        // Some state verification
		
        // counter that records how many proxy objects are currently instantiated
        long num = nextUniqueNumber.getAndIncrement();
        // Dynamic proxy object name concatenation! Package name + "$Proxy" + number
        String proxyName = proxyPkg + proxyClassNamePrefix + num;

        // Generate a bytecode file that returns an array of bytes
        byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
            proxyName, interfaces, accessFlags);
        try {
            // Use the bytecode file to create the bytecode Class object
            return defineClass0(loader, proxyName,
                                proxyClassFile, 0, proxyClassFile.length);
        } catch (ClassFormatError e) {
            throw newIllegalArgumentException(e.toString()); }}}Copy the code

There are two very important methods to note in the apply() method:

  • ProxyGenerator.generateProxyClass(): it’s a method that generates a bytecode file, which returns an array of bytes, and a bytecode file is essentially an array of bytes, soproxyClassFileAn array is a bytecode file
  • defineClass0(): the Class object that generates the bytecode file, which is anativeLocal methods, which call methods at the bottom of the operating system to create class objects

While proxyName is the name of the proxy object, we can see that it uses proxyClassNamePrefix + counter to concatenate a new name. So when you DEBUG, stay on the proxy object variable and you’ll see that the variable name is $Proxy0.

Here, the source code analysis is done, do you feel hollow? Hahaha, I felt that way too, but now you can see that JDK dynamic proxies aren’t that complicated (if you have the willpower).

CGLIB

CGLIB (Code Generation Library) is a bytecode generation Library that dynamically generates proxy classes to Java classes and Java interface extensions at runtime.

CGLIB can Proxy Java interfaces as well as ordinary Java classes. JDK Proxies can only Proxy Java classes that implement interfaces, so CGLIB extends Java proxies nicely. If the class requiring the proxy does not implement an interface, you can choose Cglib as a tool to implement dynamic proxies.

CGLIB can delegate Java classes that do not implement interfaces

Let’s learn how to use it. Take the background of xiao Ming’s story about buying French perfume from a factory as an example.

(1) Import dependencies

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib-nodep</artifactId>
    <version>3.3. 0</version>
    <scope>test</scope>
</dependency>
Copy the code

There is also another CGLIB package, the difference between which is that the dependencies with -nodep already include the ASM bytecode framework inside, without additional dependencies on ASM

The CGLIB proxy has two core classes: the MethodInterceptor interface, which implements the root interface of a proxy factory, and the Enhancer class, which creates dynamic proxy objects.

First let’s define the proxy Factory SellProxyFactory.

public class SellProxyFactory implements MethodInterceptor {
    // Control access to real objects by associating them with real objects
    private Object realObject;
    /** Get a proxy object instance from the proxy factory, which is equivalent to creating a little red proxy */
    public Object getProxyInstance(Object realObject) {
        this.realObject = realObject;
        Enhancer enhancer = new Enhancer();
        // Set the classloader for the class to be enhanced
        enhancer.setClassLoader(realObject.getClass().getClassLoader());
        // Set the proxied class, real object
        enhancer.setSuperclass(realObject.getClass());
        // Set method interceptor, proxy factory
        enhancer.setCallback(this);
        // Create the proxy class
        return enhancer.create();
    }
    
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        doSomethingBefore(); // Pre-enhanced
        Object object = methodProxy.invokeSuper(o, objects);
        doSomethingAfter(); // post-enhance
        return object;
    }

    private void doSomethingBefore(a) {
        System.out.println("Additional action before executing method...");
    }

    private void doSomethingAfter(a) {
        System.out.println("Additional operations after executing methods..."); }}Copy the code

The Intercept () method involves four parameters:

  • Object O: the proxy Object
  • Method Method: The Method to be intercepted
  • Object[] objects: All input parameters of the intercepted method
  • MethodProxy: MethodProxy, used to invoke the original method

For methods called with the methodProxy parameter, there are two internal options: invoke() and invokeSuper(). The difference between invoke and invokeSuper is not explained in this article, but should be referred to Cglib source code to analyze the difference between invoke and invokeSuper

In the getInstance() method, the Enhancer class instantiates the proxy object (which can be seen as little Red) and returns it to the caller, Xiaoming, to complete the proxy operation.

public class XiaoMing {
    public static void main(String[] args) {
        SellProxyFactory sellProxyFactory = new SellProxyFactory();
        // Get a proxy instance
        SellPerfumeFactory proxyInstance =
                (SellPerfumeFactory) sellProxyFactory.getProxyInstance(new SellPerfumeFactory());
        // Create the proxy class
        proxyInstance.sellPerfume(1999.99); }}Copy the code

We still focus on scalability and maintainability. Cglib still conforms to the open and closed principle. If Xiao Ming needs Xiao Hong’s agent to buy wine, what should he do? Here due to space reasons, I will not post the complete code, you can try to implement it, or have a general implementation idea in mind.

Let’s summarize the CGLIB dynamic proxy:

(1) Use of CGLIB:

  • Agency factory needsImplements the MethodInterceptor interface, rewrite the method,Internally associated with real objectsTo control third party access to the real object; Agent factory internal exposuregetInstance(Object realObject)Method,Use to get a proxy object instance from the proxy factory.
  • EnhancerClass is used to instantiate a proxy object from the proxy factory to provide the proxy service to the caller.

JDK Proxy vs. CGLIB

(2) JDK Proxy and CGLIB have similarities:

JDK Proxy CGLIB
The agent factory implements the interface InvocationHandler MethodInterceptor
Construct the proxy object to the Client service Proxy Enhancer

Both use two core classes, and they are also different:

  • The most obvious difference: CGLIB can act as a proxy for most classifications (point 2); JDK Proxies can only Proxy classes that implement the interface

  • CGLIB intercepts methods dynamically by creating subclasses of proided classes that override the intercepted methods internally, so CGLIB cannot proide classes and methods that are modified by the final keyword

Careful readers will find that everything is tasted, didn’t you tell me the source code, hydrological hammer), the very essence of the dynamic proxy is program dynamically generated proxy class objects at runtime, intercept method is called, in the calling method before and after the extension of additional functions, and generate dynamic proxy objects principle is reflection mechanism, in the previous article, I talked at length about how reflection is used to instantiate objects and call methods… Used in proxies, so reflection and proxies are a natural match, and talking about one means talking about the other.

Practical application of dynamic proxy

Traditional OOP programming conforms to the top-down coding relationship, but not the left-to-right coding relationship. If you can’t read the GIF below, OOP allows us to execute method by method from top to bottom, but it can’t embed code from left to right. AOP is a good way to compensate for this. It allows us to extract duplicate code logic into a single overlay that can be embedded insensibly into the original code logic as the code executes.

Spring AOP

As you can see in the figure below, method1 and method2 both need to Log before and after method execution. There are actually more methods that need to Log. Traditional OOP only allows you to Log manually before and after each method. Unable to focus on its own logic inside a method.

AOP can wrap this repetitive code in an extra layer, listening for method execution, and when a method is called, the generic logging layer intercepts the method and logs it before and after the method is called, allowing the method to focus on its business logic without other unnecessary information.

Spring AOP has many features: it provides caching, it provides logging wrap, and it handles transactions… here, I’ll use transactions as an example to show you how Spring uses dynamic proxies underneath.

Spring’s transaction involves a core annotations @ Transactional, believes that many people are used in the project, add the annotation, if an exception occurs during execution method, this method in all transaction rollback, otherwise all submitted to take effect, this is the most macro performance, it is how to implement internal? Let’s do a quick analysis today.

Each database operation ensures that all operations within a transaction either succeed or fail. Traditional transaction failure rollback and successful commit are performed using a try… The catch block is done

SqlSession session = null;
try{
    session = getSqlSessionFactory().openSession(false);
    session.update("...".new Object());
    // Transaction commit
    session.commit();
}catch(Exception e){
    // Transaction rollback
    session.rollback();
    throw e;
}finally{
    // Close the transaction
    session.close();
}
Copy the code

The Transactional annotation @Transactional is very redundant if multiple methods need to write this logic, so Spring has wrapped this annotation with the @Transactional annotation. Using this annotation, the Transactional annotation monitors the method when it is called, and automatically wraps the code for database related operations if it contains this annotation. Eventually form is similar to the above principle, a piece of code here, of course, is not accurate, just to give you a general overview, understand the nature of Spring AOP’s doing, this article explained here, utility should be very much, digested the above knowledge, for the back of the Spring AOP monographic study to lay a solid foundation.

Hello, MY name is Cxuan. I have handwritten four PDFS, including Java basic summary, HTTP core summary, computer basic knowledge and operating system core summary. I have sorted them into PDFS.