Spring framework (proxy mode)

Posted by jinky32 on Mon, 29 Nov 2021 21:14:59 +0100

catalogue

1. Agent mode

1.1 create project

1.1.1 create project

1.1.2 complete the entry code test

1.1.3 editing UserService

1.1.4 how does the business layer control transactions

1.1.4 business code - problem description

1.2 agency mechanism

1.2.1 characteristics of agent mode

1.2.1 agency characteristics

1.3 dynamic agent JDK mode

1.3.1 description of JDK agent

1.3.2 editing agent class  

  1.3.3 edit test class

1.4 dynamic agent JDK mode case

1.4.1 edit proxy object

  1.4.2 edit test method

1.5 dynamic agent - CGLIB agent

1.5.1 CGLIB description

1.5.2 CGLIB agent mode

1.5.3 cglib agent test class

  1.6 summary of JDK agent and CGlib agent (elevation / Architecture)!!!

2. Introduction to spring AOP

2.1 create project

2.1.1 basic structure

  2.1.2 hierarchical code structure

2.1.3 hierarchical code structure  

2.2 AOP

2.2.1 AOP introduction

2.2.2 AOP introduction case

2.3 common notification types

1. Agent mode

1.1 create project

1.1.1 create project

1.1.2 complete the entry code test

1.1.3 editing UserService

1.1.3.1 edit Service interface

package com.jt.service;

public interface UserService {

    void addUser();
}

  1.1.3.2 edit ServiceImpl implementation class

package com.jt.service;

import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService{

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

1.1.4 how does the business layer control transactions

Transaction: can guarantee the / atomicity / consistency / persistence / isolation of data
Note: the transaction of the database needs to be considered during the operation of the business layer. The code structure is as follows:

package com.jt.service;

import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService{

    @Override
    public void addUser() {
        try {
            System.out.println("Open database transaction");
            System.out.println("New user");
            int a = 1/0;
            System.out.println("Commit database transactions");
        }catch (Exception e){
            System.out.println("Transaction rollback");
        }
    }
}

1.1.4 business code - problem description

  1. If there are multiple methods, each method needs to control the transaction. The code repetition rate is high
  2. The business layer service should only deal with business and should not be coupled with transaction code. Otherwise, it has poor scalability and high coupling

How to solve it: use the agent mechanism to solve it

1.2 agency mechanism

1.2.1 characteristics of agent mode

Note: generally, the agent mode is adopted, and the main purpose is to decouple. Put the common method (function / business) into the agent object. The business layer can focus on business execution

1.2.1 agency characteristics

  1. Why use proxy? Because they are inconvenient (no resources)
  2. The role of agents? The agent has to solve (extend) some practical problems
  3. User end execution target method!!!

1.3 dynamic agent JDK mode

1.3.1 description of JDK agent

  1. JDK proxy mode is an API provided by java natively, and there is no need to import packages
  2. JDK agent requirements: the agent must   Either interface or implement interface
  3. Flexibility: the agent as like as two peas! (same method)

1.3.2 editing agent class  

package com.jt.proxy;

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

public class JDKProxy {

    //Pass in the target object to get the name of the proxy object
    //Extension of method using proxy object
    public static Object getProxy(Object target){
        //1. Get class loader
        ClassLoader classLoader = target.getClass().getClassLoader();
        //2. Get interface array type
        Class[] interfaces = target.getClass().getInterfaces();
        //3. Callback method when proxy object executes method (invocationhandler is executed when proxy object calls method)
        return Proxy.newProxyInstance(classLoader,interfaces,invocationHandler(target));
    }

    //The target object must be passed
    public static InvocationHandler invocationHandler(Object target){
       return new InvocationHandler() {
           @Override
           public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
               System.out.println("Transaction on");
               //Gets the return value of the target method
               Object result = method.invoke(target,args);
               System.out.println("Transaction commit");
               return result;
           }
       };
    }
}

  1.3.3 edit test class

package com.jt;

import com.jt.config.SpringConfig;
import com.jt.proxy.JDKProxy;
import com.jt.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestSpring {

    @Test
    public void demo1(){
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        //Get target object
        UserService userService = context.getBean(UserService.class);
        //userService.addUser();
        //Get proxy object
        UserService proxy = (UserService) JDKProxy.getProxy(userService);
        //The proxy object executes the method and calls the invoke method
        proxy.addUser();
    }
}

 

1.4 dynamic agent JDK mode case

Requirement: you are required to calculate the running time of addUser() method? Dynamic agent is required

1.4.1 edit proxy object

 public static Object getTimePorxy(Object target){
        ClassLoader classLoader = target.getClass().getClassLoader();
        Class[] interfaces = target.getClass().getInterfaces();
        return Proxy.newProxyInstance(classLoader,interfaces,invocationHandlerTime(target));
    }

    //The target object must be passed
    public static InvocationHandler invocationHandlerTime(Object target){
        return new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //start time
                long startTime = System.currentTimeMillis();
                //Let the target method execute the result
                Object result = method.invoke(target,args);
                long endTime = System.currentTimeMillis();
                System.out.println("time consuming:"+(endTime - startTime));
                return result;
            }
        };
    }

  1.4.2 edit test method

 

package com.jt;

import com.jt.config.SpringConfig;
import com.jt.proxy.JDKProxy;
import com.jt.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestSpring {

    @Test
    public void demo1(){
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        //Get target object
        UserService userService = context.getBean(UserService.class);
        System.out.println(userService.getClass());
        //userService.addUser();
        //Get proxy object
        UserService proxy = (UserService) JDKProxy.getTimePorxy(userService);
        System.out.println(proxy.getClass());
        //The proxy object executes the method and calls the invoke method
        proxy.addUser();
    }
}

1.5 dynamic agent - CGLIB agent

1.5.1 CGLIB description

JDK proxy: it is required to have / implement an interface. If there is no interface, the JDK proxy cannot execute normally
cglib proxy: it is required that the agent can have an interface or not   The proxy object is a subclass of the target object   Override subclass methods

1.5.2 CGLIB agent mode

package com.jt.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CGlibProxy {

    public static Object getProxy(Object target){
        //1. Create an intensifier object
        Enhancer enhancer = new Enhancer();
        //2. Set parent target object
        enhancer.setSuperclass(target.getClass());
        //3. The callback method is defined and called when the proxy object executes the target method
        enhancer.setCallback(getMethodInterceptor(target));
        //4. Create proxy object
        return enhancer.create();
    }
    //target object needs to be passed
    public static MethodInterceptor getMethodInterceptor(Object target){
        return new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println("Transaction start");
                //Execution target method
                Object result = method.invoke(target,args);
                System.out.println("Transaction commit");
                return result;
            }
        };
    }
}

1.5.3 cglib agent test class

@Test
    public void demo2(){
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        //Get target object
        UserService userService = context.getBean(UserService.class);
        UserService proxy = (UserService) CGlibProxy.getProxy(userService);
        System.out.println(proxy.getClass());
        proxy.addUser();
    }

 

  1.6 summary of JDK agent and CGlib agent (elevation / Architecture)!!!

1. JDK requires that there must be or implement interfaces. cglib can create proxy objects with or without interfaces. Proxy objects are subclasses of target objects
2. JDK proxy tool API: proxy.newproxyinstance (class loader, interface array, invocationHandler interface)
3. CGlib proxy tool API: Enhancer enhancer object gets the proxy object enhancer.create(); Callback interface
MethodInterceptor interface
4. Execute target method in JDK
-method.invoke(target,args);
Execute target method in CGlib
-method.invoke(target,args);
 

2. Introduction to spring AOP

2.1 create project

2.1.1 basic structure

 

  2.1.2 hierarchical code structure

2.1.3 hierarchical code structure  

  <!--introduce AOPjar Package file-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2.2 AOP

2.2.1 AOP introduction

In the software industry, AOP is the abbreviation of Aspect Oriented Programming, which means: Aspect Oriented Programming, a technology to realize the unified maintenance of program functions through precompiled mode and dynamic agent during operation. 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.

Summary: AOP in Spring uses proxy objects to extend methods without modifying the source code

 

2.2.2 AOP introduction case

2.2.2.1 edit configuration class

@Configuration
@ComponentScan("com.jt") //Packet scanning
@EnableAspectJAutoProxy  //Turn on AOP
public class SpringConfig {


}

  2.2.2.2 edit section class

package com.jt.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component  //Leave the class to Spring container management!!!
@Aspect     //Identifies that the class is a facet
public class SpringAOP {
    /**
     * Knowledge review: AOP uses dynamic agents to expand the target method
     * Formula: facet = pointcut expression + notification method
     * Pointcut expression: if the target object satisfies the judgment (if) of the pointcut expression, spring automatically creates a proxy object for it
     * Notification method: an encapsulation method that extends the target method
     * ID of the bean of the target object: userserviceimpl
     * Pointcut expression:
     *      1. bean("bean ID of)
     * AOP Rule: if the target object satisfies the pointcut expression, the notification method is executed
     */
    @Pointcut("bean(userServiceImpl)")
    public void pointcut(){

    }

    //Pre - Notification: executed before the target method is executed
    @Before("pointcut()")
    public void before(){
        System.out.println("I'm an advance notice!!!!");
    }
}

2.2.2.3 edit test class

package com.jt;

import com.jt.config.SpringConfig;
import com.jt.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestSpring {

    @Test
    public void demo1(){
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        //It is the target object, but if it matches the pointcut expression, the proxy object is generated dynamically
        UserService userService = context.getBean(UserService.class);
        System.out.println(userService.getClass());
        //Because it is a proxy object, the method can be extended
        userService.addUser();
    }
}

2.3 common notification types

package com.jt.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component  //Leave the class to Spring container management!!!
@Aspect     //Identifies that the class is a facet
public class SpringAOP {
    /**
     * Knowledge review: AOP uses dynamic agents to expand the target method
     * Formula: facet = pointcut expression + notification method
     * Pointcut expression: if the target object satisfies the judgment (if) of the pointcut expression, spring automatically creates a proxy object for it
     * Notification method: an encapsulation method that extends the target method
     * ID of the bean of the target object: userserviceimpl
     * Pointcut expression:
     *      1. bean("bean ID of)
     * AOP Rule: if the target object satisfies the pointcut expression, the notification method is executed
     */
    @Pointcut("bean(userServiceImpl)")
    public void pointcut(){

    }

    //1. Pre notification: executed before the target method is executed
    @Before("pointcut()")
    public void before(){
        System.out.println("I'm an advance notice!!!!");
    }

    //2. Post notification: executed after the target method is executed
    @AfterReturning("pointcut()")
    public void afterReturn(){
        System.out.println("I'm a post notification!!!!");
    }

    //3. Exception notification: this notification is executed when the target method reports an error
    @AfterThrowing("pointcut()")
    public void afterThrowing(){
        System.out.println("I'm an exception notification!!!!");
    }

    //4. Final notice: the notice to be executed after the target method
    @After("pointcut()")
    public void after(){
        System.out.println("The final notice shall be executed");
    }

    //5. Focus on mastering the surrounding notice: implement it before and after the implementation of the target method. Control the target method
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Before execution of surround notification!!!!");
        //The underlying layer calls the invoke method of the dynamic agent to execute the target method
        Object result = joinPoint.proceed();
        System.out.println("After the notification is executed!!!!");
        return result;
    }
}

Topics: Front-end Spring html css