Agent mode, AOP

Keywords: Java Spring


Learning website: station b mania

proxy pattern

Why learn proxy mode? Because this is the bottom level of Spring AOP! [Spring AOP and Spring MVC are important]

Classification of agent modes:

  • Static Proxy
  • Dynamic Proxy


Static Proxy

Role Analysis:

  • Abstract Role: An interface or abstract class is typically used to solve the problem
  • Real Role: The Role to be Agented
  • Agent role: Active real role, after acting real role, we will do some subsidiary actions
  • Customer: The person who visits the agent!

Code steps:

1. Interface

//Rental
public interface Rent {

    public void rent();

}

2. Real Role

//Landlord or landlady
public class Host implements Rent{

    public void rent() {
        System.out.println("The landlord wants to rent a house!");
    }
}

3. Agent Role

public class Proxy implements Rent {

    private Host host;

    public Proxy() {
    }

    public Proxy(Host host) {
        this.host = host;
    }

    public void rent() {
        seeHouser();
        host.rent();
        heTong();
        fare();
    }

    //Housekeeping
    public void seeHouser(){
        System.out.println("The intermediary takes the customer to the room!");
    }

    //Sign a contract
    public void heTong(){
        System.out.println("Sign the lease contract!");
    }

    //Collecting intermediary fees
    public void fare(){
        System.out.println("Intermediary fee!");
    }
}

4. Client Access Proxy Role

//customer
public class Client {

    public static void main(String[] args) {

        //We need to go to an intermediary to find a house.
//        Host host = new Host();
//        host.rent();

        //Find a landowner who wants to rent a house
        Host host = new Host();

        //Agents, intermediaries will generally help landlords rent houses, but will do some subsidiary operations
        Proxy proxy = new Proxy(host);

        //Instead of facing the landlord directly, just look for an intermediary rental
        proxy.rent();
    }

}

Benefits of the proxy model:

  • Can make real character operations more pure! Will not focus on some public business
  • Public, that is, delegate role, achieves division of business
  • When public services are expanded to facilitate centralized management

Disadvantages:

  • A real role produces a proxy role, which can overwhelm code and be inefficient

acquire a better understanding

Talk about AOP

Code steps:

1. Interface

public interface UserDao {
    public void add();
    public void delete();
    public void update();
    public void query();
}

2. Real Role

//Real object
public class UserImple implements UserDao {
    public void add() {
        System.out.println("Add a user!");
    }

    public void delete() {
        System.out.println("Deleted a user!");
    }

    public void update() {
        System.out.println("Modified a user!");
    }

    public void query() {
        System.out.println("Queried a user!");
    }
}

3. Agent Role

public class UserProcy implements UserDao {

    private UserImple userImple;

    public UserImple getUserImple() {
        return userImple;
    }

    public void setUserImple(UserImple userImple) {
        this.userImple = userImple;
    }

    public void add() {
        log("add");
        userImple.add();
    }

    public void delete() {
        log("delete");
        userImple.delete();
    }

    public void update() {
        log("update");
        userImple.update();
    }

    public void query() {
        log("query");
        userImple.query();
    }

    //Logging Method
    public void log(String str)
    {
        System.out.println("Used"+str+"Method");
    }
}

4. Client Access Proxy Role

public class Client {
    public static void main(String[] args) {
        UserImple userImple = new UserImple();

        UserProcy userProcy = new UserProcy();

        userProcy.setUserImple(userImple);

        userProcy.add();
        userProcy.delete();
        userProcy.update();
        userProcy.query();
    }     
}

Dynamic Proxy

  • Dynamic proxy is the same as static proxy role
  • Dynamic proxy classes are dynamically generated, not written by us
  • Dynamic proxies are divided into two categories: interface-based dynamic proxy and class-based dynamic proxy.
    • Interface-based - JDK Dynamic Proxy
    • Class-based: cglib
    • java byte code implementation: javasist

You need to understand two classes: proxy: proxy InvocationHandler: call handler

InvocationHandler:

.Interface

//Rental
public interface Rent {

    public void rent();

}

2. Real Role

//Landlord or landlady
public class Host implements Rent {

    public void rent() {
        System.out.println("The landlord wants to rent a house!");
    }
}

3. Classes for dynamic proxy implementation

//We'll use this class later to automatically generate the proxy class
public class ProxyInvocationHandler implements InvocationHandler {

    //Agented Interface
    private Rent rent;

    public void setRent(Rent rent) {
        this.rent = rent;
    }

    //Generated Proxy Class
    public Object getProxy(){

        //This code is dead, we just need to change the value of the rent parameter
        Object o = Proxy.newProxyInstance(this.getClass().getClassLoader(),
                rent.getClass().getInterfaces(), this);

        return o;
    }

    //Process the proxy instance and return the results
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        seeHouse();
        //The essence of dynamic proxy is to use reflection mechanism to implement
        Object invoke = method.invoke(rent, args);

        fare();

        return invoke;
    }

    public void seeHouse(){
        System.out.println("Look at the house");
    }

    public void fare(){
        System.out.println("Collecting intermediary fees");
    }
}	

4. Client Access Proxy Role

public class Client {
    public static void main(String[] args) {
        //Real Role
        Host host = new Host();

        //Agent role: not available at this time
        ProxyInvocationHandler p = new ProxyInvocationHandler();

        //Handle the interface object we want to call by calling the program to handle the role
        p.setRent(host);

        Rent proxy = (Rent) p.getProxy();

        proxy.rent();
    }
}

Benefits of dynamic proxy:

  • Can make real character operations more pure! Don't focus on some public business
  • The public will also be given the role of agent! The division of business has been achieved!
  • Convenient centralized management when public business expands!
  • A dynamic proxy class proxy is an interface, typically a corresponding type of business
  • A dynamic proxy class can proxy multiple classes as long as it implements the same interface

AOP

What is AOP

AOP (Aspect Oriented Programming)Meaning: Aspect-oriented programming, a technology for unified maintenance of program functions through precompilation and runtime dynamic proxy. AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework, and a derived paradigm of functional programming. AOP can be used to isolate parts of business logic, thus enabling businessDecreased coupling between logical parts improves the reusability of the program and the efficiency of development.


Role of AOP in Spring

The Role of Aop in Spring

Provide declarative transactions; allow users to customize facets

The following nouns need to be understood:

  • Crosscutting concerns: Methods or functions that span multiple modules of an application. That is, irrelevant to our business logic, but what we need to focus on is crosscutting concerns. Logs, security, caching, transactions, and so on...
  • Aspect (ASPECT): A special object whose cross-sectional focus is modularized. That is, it is a class.
  • Advice: The work that a facet must do. That is, it is a method in a class.
  • Target: Notified object.
  • Proxy: An object created after notification is applied to the target object.
  • PointCut: Definition of "place" for facet notification execution.
  • JointPoint: The execution point that matches the entry point.



Implement AOP using Spring

To Import Packages

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.9.4</version>
</dependency>

Mode 1: Implement using the spring API

Write our business interface and implementation class first

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void query();
}
public class UserServiceImple implements UserService {
    public void add() {
        System.out.println("Add a user!");
    }

    public void delete() {
        System.out.println("Deleted a user!");
    }

    public void update() {
        System.out.println("Modified a user!");
    }

    public void query() {
        System.out.println("Queried a user!");
    }
}

Then to write our enhancement class, we write two, one pre-enhanced and one post-enhanced

Pre-enhancement:

public class LOg implements MethodBeforeAdvice {

    //method: method of the target object to execute
    //args:parameter
    //target:Target Object
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"Of"+method.getName()+"To be executed!");
    }
}

Post Enhancement:

public class AfterLog implements AfterReturningAdvice {

    //returnValue:Return value
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("Executed"+method.getName()+"Method, returns the following results:"+returnValue);
    }
}

Finally, register in the spring file and implement aop cut-in implementation, paying attention to import constraints:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--register bean-->
    <bean id="userService" class="com.yunk.service.UserServiceImple"></bean>
    <bean id="log" class="com.yunk.log.LOg"/>
    <bean id="afterLog" class="com.yunk.log.AfterLog"/>

    <!--Mode 1: Use spring API Java Native Interface-->
    <!--To configure AOP:Need to import aop Constraints of-->
    <aop:config>
        <!--Start Point: expression:Expression, execution(Location to execute! * * * * (..))  (..)Represents all parameters-->
        <aop:pointcut id="pointcut" expression="execution(* com.yunk.service.UserServiceImple.*(..))"/>

        <!--Enforce Surround Increase-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>

</beans>

Test:

public class Test {
    public static void main(String[] args) {
        ApplicationContext c =
                new ClassPathXmlApplicationContext("applicationContext.xml");

        //Dynamic proxy proxies are interfaces
        UserService userService = (UserService) c.getBean("userService");

        userService.add();
    }
}

Mode 2: Custom class implements AOP

Remove pre-enhancements and post-enhancements and add a new class. Customize and use whatever methods you want.

public class DiyPointCut  {

    public void before()
    {
        System.out.println("Before method execution!");
    }

    public void after(){
        System.out.println("After method execution!");
    }
}

Finally, register in the spring file and implement aop cut-in implementation, paying attention to import constraints:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--register bean-->
    <bean id="userService" class="com.yunk.service.UserServiceImple"></bean>
    <bean id="log" class="com.yunk.log.LOg"/>
    <bean id="afterLog" class="com.yunk.log.AfterLog"/>

    <!--Mode 2: Custom class implementation AOP-->
    <bean id="diyPointCut" class="com.yunk.diy.DiyPointCut"/>

    <aop:config>

        <!--Custom facets, ref Class to Reference-->
        <aop:aspect ref="diyPointCut">

            <!--breakthrough point-->
            <aop:pointcut id="point" expression="execution(* com.yunk.service.UserServiceImple.*(..))"/>

            <!--notice-->
            <!--before,stay point Execute before corresponding method
                after,stay point Execute after corresponding method
                    method For the method to be executed, from the class referenced in the cut-in-->
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>
</beans>

Mode 3: Using annotations to implement

Customize a class:

package com.yunk.diy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

//Mode 3: Using annotations to implement AOP

/*In Mode 2, we need to <!--Custom facets, ref class to reference -->
                                 <aop:aspect ref="diyPointCut">
             We define this class directly as a tangent class using the annotation @Aspect*/

@Aspect
public class AnnotationPointCut {

    @Before("execution(* com.yunk.service.UserServiceImple.*(..))")//Cut-in, cut-in methods are all available, but there is a gap
    public void before()
    {
        System.out.println("1.Before method execution!");
    }

    @After("execution(* com.yunk.service.UserServiceImple.*(..))")
    public void after(){
        System.out.println("After method execution!");
    }

    /* In surround enhancement, we can give a parameter that represents where we want to get started*/
    @Around("execution(* com.yunk.service.UserServiceImple.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("Before Surround");
        //Execution Method
        //Signature signature = jp.getSignature();//Get Signature
        //System.out.println("signature"+signature);
        jp.proceed();
        System.out.println("After Surround");
    }
}

We also need to write in the configuration file:

 <!--Mode 3: Using annotations to implement AOP-->
    <!--We also need a configuration file to bring in the class registrar-->
    <bean id="anno" class="com.yunk.diy.AnnotationPointCut"/>
    <!--Turn on annotation support-->
    <aop:aspectj-autoproxy/>
adopt aop Namespace<aop:aspectj-autoproxy />Declare automatically as spring Configurations in Containers@aspectJ Sectional bean Create a proxy to weave into facets. Of course, spring Still used internally AnnotationAwareAspectJAutoProxyCreator Auto-proxy creation is done, but the details of the implementation have been<aop:aspectj-autoproxy />Hidden

<aop:aspectj-autoproxy />There is one proxy-target-class Property, default is false,Indicates use jdk Dynamic proxy weaving enhancements when paired with<aop:aspectj-autoproxy  poxy-target-class="true"/>When the CGLib Dynamic proxy technology weaving enhancements. But even if proxy-target-class Set to false,If the target class does not declare an interface, spring Will be used automatically CGLib Dynamic proxy.

Posted by alienmojo on Wed, 29 Sep 2021 10:25:17 -0700