Spring-Day04-AOP transaction introduction

Posted by linkskywalker on Fri, 18 Feb 2022 19:42:06 +0100

Copyright notice: This article is the original article of shining sun and follows the CC 4.0 BY-SA copyright agreement. For reprint, please attach the source link of the original text and this notice.
Original link: https://blog.csdn.net/qq_16804847/article/details/116116965OP

1.AOP

1.1 AOP case introduction

1.1.1 database transaction description

Case study:
1. userMapper.insert(User object)
2. deptMapper.insert(dept object)
Note: due to business requirements, the method must be either received or rolled back at the same time Therefore, it must be controlled through transactions

1.2 Spring implements transaction control (demo)

1.2.1 the code structure is as follows:

1.2.2 edit UserMapper/UserMapperImpl

1). Edit UserMapper

2). Edit UserMapperImpl

1.2.3 edit UserService/UserServiceImpl

1). Edit UserService

2) Edit UserServiceImpl

1.2.4 edit configuration class

1.2.5 edit test class

1.3 code problem analysis


Solution: edit in proxy mode

1.4 agent mode

1.4.1 agency cases in life

Housing agency mode:
1. Landlord: I have a house in my hand and need to rent it for money
2. Intermediaries 1 My job is to show customers / rent houses 2 Charge intermediary fee (service fee)
3. Tenants: rent houses to meet their own needs

Code thinking modeling:
1. Expose a public interface (rent a house)
2. The customer communicates with the intermediary, which seems to have the same function as the landlord
(the agent appears to be the real object)
3. Complete additional operations of users (charge intermediary fee)

1.4.2 agent mode

1). component
1. The agent is required to implement the same interface as the agent
2. Implement the function extension in the agent method
3. The user calls the proxy object to complete the function (the user thinks the proxy is the target object)

2). Call process

1.5 static agent

1.5.1 transaction control through agent mode

Role division:
1. Target object target UserServiceImpl class
2. Target method addUser() method
3. Agent: realize transaction control
4. The proxy object and the target object implement the same interface

1.5.2 modify target object name

1.5.3 editing agent class

@Service("userService")
public class StaticProxy implements UserService {

    //Target objects are required to be imported
    @Autowired //ByType  byName
    //@Qualifier("target")
    private UserService target;

    //Objective: to extend the original method
    @Override
    public void addUser(User user) {
        try {
            System.out.println("Transaction start");
            target.addUser(user);
            System.out.println("End of transaction");
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("Transaction rollback");
        }
    }
}

1.5.4 edit test class

@Test
    public void testStaticProxy(){
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = (UserService) context.getBean("userService");
        User user = new User();
        user.setId(10001);
        user.setName("Test agent mechanism");
        //Execute user call
        userService.addUser(user);
    }

1.5 disadvantages of static agent

1). Static proxy is only aimed at one interface, and the proxy that cannot implement all interfaces has poor practicability

2). All methods in static agent need to add transaction start / transaction commit code manually. The code redundancy is not concise enough

1.6 dynamic agent mechanism

1.6.1 dynamic agent classification (test questions)

1.JDK agent:
Requirement: the target object must implement the interface
Proxy requirements: the proxy object must also implement the interface of the target object
Target object / proxy relationship: sibling relationship between target object and proxy object

2.CGlib agent
Requirement: no matter whether the target object has an interface or not, you can create a proxy object for it
Proxy requirement: the proxy object must inherit from the target object
Target object / proxy relationship: the target object and proxy object are parent-child relationships

1.6.2 edit JDK dynamic agent

Official website API:

Recite knowledge points:
1. Usage description of anonymous inner class: anonymous inner class refers to external parameters, which must be modified by final
2. This method identifies the "callback" method when the proxy object executes
java public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {}
3. Target method implementation
java result = method.invoke(target,args);

package com.jt.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//Can a factory be used to dynamically create proxies for target objects
public class JDKProxyFactory {

    //Ask the user to pass the target object
    //Usage notes on anonymous inner class: anonymous inner class refers to external parameters. It is required that the parameters must be final modified
    public static Object getProxy(final Object target){
        //1. Call java API to realize dynamic proxy
        /**
         *  Parameter analysis: 3 parameters
         *      1.ClassLoader loader, Class loader (get the class of the target object)
         *      2.Class <? > [] interfaces, JDK agent requires interfaces
         *                             java It can be implemented in many ways
         *      3.InvocationHandler h  Extend the target method
         */
        //1. Get class loader
        ClassLoader classLoader = target.getClass().getClassLoader();
        //2. Get interface array
        Class[] interfaces = target.getClass().getInterfaces();
        //3. Create objects through dynamic proxy
        Object proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {

            //Invoke method: when the proxy object invokes the method, invoke executes and extends the editing position of the method
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // The return value of the result method of the execution target
                Object result = null;
                try {
                    //Add control of transactions
                    System.out.println("Transaction start");
                    //Execution target method
                    // Target real target object, method object, args method parameter
                    result = method.invoke(target,args);
                    System.out.println("Transaction commit");
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("Transaction rollback");
                }
                return result;
            }
        });

        return proxy;
    }
}

1.6.3 JDK dynamic agent execution process

1.7 dynamic agent advantages

Write the public part into the dynamic proxy, and then call other business classes

1.7.1 edit DeptService/DeptServiceImpl

1). Edit DeptService

2). Edit DeptServiceImpl

1.7.2 edit test class

public class TestDept {

    @Test
    public void testTx(){
        //1. Get the target object
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        DeptService target = (DeptService) context.getBean("deptService");
        //2. Get proxy object
        DeptService deptService = (DeptService) JDKProxyFactory.getProxy(target);
        //The method is extended by calling the method through the proxy object!!!!!
        deptService.addDept();  //invoke
    }
}

1.8 implementation scheme of dynamic agent (II)

1.8.1 business requirements

It is required to record the execution time of the Service layer method!!! Targeted optimization through the length of execution time!!!
Requirement: there is addUser method / deleteUser method in the service
It requires good code structure expansibility and low coupling
Finish 1000 yuan!!!

1.8.2 edit UserService/UserServiceImpl

1). Edit UserService

public interface UserService {

    void addUser(User user);
    void deleteUser(User user);
}

2). Edit UserServiceImpl

@Service("target")
public class UserServiceImpl implements UserService{

    @Override
    public void addUser() {
        System.out.println("New user");
    }

    @Override
    public void deleteUser() {
        System.out.println("delete user");
    }
}

1.8.3 edit agent factory

package com.jt.proxy;

import javax.annotation.PostConstruct;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JDKProxyFactory {

    //Edit static method to get proxy object
    public static Object getProxy(final Object target){
        //3 parameters 1 Class loader 2 Object interface
        ClassLoader classLoader = target.getClass().getClassLoader();
        Class[] interfaces = target.getClass().getInterfaces();
        Object proxy = Proxy.newProxyInstance(classLoader, interfaces,
                new InvocationHandler() {
                    //Executed when the proxy object executes the target method
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        //Let the user execute the target method
                        Long startTime = System.currentTimeMillis(); //start time
                        //The return value obtained by executing the target method may be null
                        Object result = method.invoke(target);
                        Long endTime = System.currentTimeMillis();  //End time
                        //According to the requirements of the project manager, bug s are reserved for the program. It is unfriendly to delete them during later maintenance
                        Thread.sleep(2000);
                        System.out.println("program execution :"+(endTime-startTime)+"millisecond");
                        //Pass the return value to the caller
                        return result;
                    }
                })  ;

        return proxy;
    }


}

1.8.4 edit test cases

public class TestSpring {

    @Test
    public void test01(){
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        //1. Get the target object
        UserService target = (UserService) context.getBean("target");
        //2. Get proxy object
        UserService proxy = (UserService) JDKProxyFactory.getProxy(target);
        System.out.println(proxy.getClass());
        //3. Business method call
        proxy.addUser();
    }
}

1.9 business case 3

1000 blocks of log control are required
When the method is required to execute, obtain the method name and the name of its class for console output And the execution time of the method

task

1). Skillfully edit 3-tier code structure for 5 times