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.