🏇
wow
Click
Click
:
\textcolor{blue} {wow, Kaka:}
Wow, Kaka:
stay
front
two
piece
in
I
Guys
Yes
solution
Yes
I
O
C
\textcolor{green} {in the first two articles, we learned about IOC}
In the first two articles, we learned about IOC
🏇
meet
lower
come
Just
meet
touch
one
lower
another
one
individual
nucleus
heart
A
O
P
\textcolor{pink} {next, let's touch on another core AOP}
Next, let's touch on another core AOP
💥The code used can be found here💥
🙏
Bo
main
also
stay
learn
Learn
rank
paragraph
,
as
if
hair
present
ask
topic
,
please
Tell
know
,
wrong
often
sense
thank
\textcolor{Orange} {blogger is also in the learning stage. If you find any problems, please let me know. Thank you very much}
Bloggers are also in the learning stage. If you find any problems, please let us know. Thank you very much 💗
🐳 Click to send you to "a brief understanding of the theoretical derivation of Spring and IOC"
🐳 Click to send you to IOC and DI in Spring
AOP
1. What is AOP
AOP (Aspect Oriented Programming) means: Aspect Oriented Programming, which realizes the same maintenance of program functions through precompiled mode and runtime dynamic agent. 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.
A O P of main want Merit can \Textcolor {orange} {main functions of AOP} Main functions of AOP
- Logging
- Performance statistics
- safety control
- transaction processing
- Exception handling, etc
Spring AOP is simply understood as a knife, which can be inserted or pulled out at will during execution.
2. The role of AOP in Spring
Provide declarative transactions; Allows you to customize the cut plane
- Crosscutting concerns: which write method to intercept and how to deal with it after interception have nothing to do with our business logic, but we need to focus on crosscutting concerns, such as logs, security, cache, transactions, etc. Methods or functions that span multiple modules of an application.
- ASPECT: a special object whose crosscutting concerns are modularized, that is, it is a class
- Advice: what aspect must do, that is, it is a method in a class
- Target: the notified object, that is, the target object of the agent.
- Proxy: an object created after notification is applied to the target object.
- PointCut: the definition of the "place" where the aspect notification is executed
- Join point: the execution point that matches the pointcut.
- weave: the process of applying facets to the target object and causing the creation of proxy objects.
In spring AOP, crosscutting logic is defined through Advice. Spring supports five types of Advice
3. Using Spring to implement AOP
[key] to use AOP weaving, you need to import a dependency package
<dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.7</version> </dependency> </dependencies>
Method 1: use Spring's api interface [mainly api interface]
UserService
package com.hxl.service; public interface UserService { public void add(); public void delete(); public void update(); public void select(); }
UserServiceImpl
package com.hxl.service; public class UserServiceImpl implements UserService{ public void add() { System.out.println("Added a user"); } public void delete() { System.out.println("A user was deleted"); } public void update() { System.out.println("Modified a user"); } public void select() { System.out.println("A user was queried"); } }
applicationContext.xml
<?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:context="http://www.springframework.org/schema/context" 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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--register bean--> <bean id="userService" class="com.hxl.service.UserServiceImpl"/> <bean id="log" class="com.hxl.log.Log"/> <bean id="afterLog" class="com.hxl.log.LogAfter"/> <!--Use native Spring API Interface--> <!--to configure aop:Import required aop Constraints of--> <aop:config> <!--breakthrough point;expression:expression,execution(Location to execute, modifier, return value, class name, method name, parameter)--> <aop:pointcut id="pointCut" expression="execution(* com.hxl.service.UserServiceImpl.*(..))"/> <!--Execute surround increase--> <aop:advisor advice-ref="log" pointcut-ref="pointCut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointCut"/> </aop:config> </beans>
Test:
import com.hxl.service.UserService; import com.hxl.service.UserServiceImpl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //Note: dynamic proxies are interfaces UserService userService = context.getBean("userService", UserService.class); userService.add(); } }
Method 2: Customize to implement aop [mainly section]
DiyPointCut
package com.hxl.diy; public class DiyPointCut { public void before(){ System.out.println("====Before method execution===="); } public void after(){ System.out.println("====After method execution===="); } }
<!--Method 2: user defined class--> <bean id="diy" class="com.hxl.diy.DiyPointCut"/> <aop:config> <!--Custom cut, ref Class to reference--> <aop:aspect ref="diy"> <!--breakthrough point--> <aop:pointcut id="point" expression="execution(* com.hxl.service.UserServiceImpl.*(..))"/> <!--notice--> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config>
Method 3: using annotations to implement aop
package com.hxl.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; //Method 3: use annotation to implement aop @Aspect//Label this class as a facet public class AnnotationPointCut { @Before("execution(* com.hxl.service.UserServiceImpl.*(..))") public void before(){ System.out.println("====Before method execution===="); } @After("execution(* com.hxl.service.UserServiceImpl.*(..))") public void after(){ System.out.println("====After method execution===="); } //In surround enhancement, we can give a parameter representing the point where we want to get the processing pointcut @Around("execution(* com.hxl.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("====Surround front===="); Signature signature = jp.getSignature();//Get signature System.out.println("signature:" + signature); //Execution method Object proceed = jp.proceed(); System.out.println("=====After surround===="); } }
<!--Mode 3:--> <bean id="annotationPointCut" class="com.hxl.diy.AnnotationPointCut"/> <!--Enable annotation support JDK(default proxy-target-class="false") cglib(proxy-target-class="true") --> <aop:aspectj-autoproxy />
proxy pattern
Why learn the proxy pattern? Because this is the bottom layer of spring AOP
During the interview, you will ask [spring AOP and apring MVC]
Agent mode is divided into static agent and dynamic agent
1. Static proxy
1.1 initial understanding
Role analysis:
- Abstract role: it is usually solved by using interfaces or abstract classes
- Real role: the role represented
- Agent role: represents the real role. There are usually some ancillary operations after the agent
- Customer: the person who accesses the proxy object!
Code steps
-
Interface
package com.hxl.demo01; //Rent a house public interface Rent { public void rent(); }
-
Real role
package com.hxl.demo01; //landlord or landlady public class Host implements Rent{ public void rent() { System.out.println("The landlord wants to rent the house"); } }
-
delegable role
package com.hxl.demo01; public class Proxy implements Rent{ private Host host; public Proxy() { } public Proxy(Host host) { this.host = host; } public void rent() { seeHouse(); host.rent(); contract(); fare(); } //House viewing public void seeHouse(){ System.out.println("The agent will show you the house"); } //sign a contract public void contract (){ System.out.println("Sign a lease contract"); } //Intermediary fee public void fare(){ System.out.println("Intermediary fee"); } }
-
Client access agent role
package com.hxl.demo01; public class Client { public static void main(String[] args) { Host host = new Host(); //Agents and intermediaries rent houses for landlords. Generally, the agent role will have some ancillary operations Proxy proxy = new Proxy(host); //Do not face the landlord, directly find an intermediary to rent a house proxy.rent(); } }
Benefits of agent mode:
- It can make the operation of real roles more pure without paying attention to some public businesses
- The public business is entrusted to the agent role to realize the division of business
- When the public business is expanded, it is convenient for centralized management
Disadvantages of agent mode:
- A real role produces a proxy role
- The amount of code will double and the development efficiency will be low
1.2 re understanding
package com.hxl.demo02; public interface UserService { public void add(); public void delete(); public void update(); public void query(); }
package com.hxl.demo02; //Real object public class UserServiceImpl implements UserService{ public void add() { System.out.println("Added a user"); } public void delete() { System.out.println("A user was deleted"); } public void update() { System.out.println("Modified a user"); } public void query() { System.out.println("A user was queried"); } }
package com.hxl.demo02; public class UserServiceProxy implements UserService{ private UserServiceImpl userService; public void setUserService(UserServiceImpl userService) { this.userService = userService; } public void add() { log("add"); userService.add(); } public void delete() { log("delete"); userService.delete(); } public void update() { log("update"); userService.update(); } public void query() { log("query"); userService.query(); } //Log method public void log(String msg){ System.out.println("[Log output]Used" + msg + "method"); } }
package com.hxl.demo02; public class Client { public static void main(String[] args) { UserServiceImpl userService = new UserServiceImpl(); UserServiceProxy proxy = new UserServiceProxy(); proxy.setUserService(userService); proxy.add(); } }
Using proxy will not change the structure of the original code, and many operations can be added in the proxy mode
A O P \textcolor{orange}{AOP} AOP
2. Dynamic agent
move state generation reason of bottom layer all yes back shoot \textcolor{orange} {the bottom layer of dynamic proxy is reflection} The bottom layer of dynamic proxy is reflection
- Dynamic agents have the same role as static agents
- The proxy class of dynamic proxy is generated dynamically, which is not written by us
- Dynamic agents are divided into two categories: interface based dynamic agents and class based dynamic agents
- Interface based - jdk dynamic agent
- Class based cglib
- java bytecode implementation: javassist
- The dynamic proxy is the interface
Two classes need to be understood: Proxy: Proxy; InvocationHandler: call handler
InvocationHandler: under the reflection package (java.lang.reflect). It is an interface implemented by the calling handler of the proxy instance. Each proxy instance has an associated calling handler. When a method is called on the proxy instance, the method call will be encoded and dispatched to the invoke method of its calling handler
Benefits of dynamic agents:
- It can make the operation of real roles more pure without paying attention to some public businesses
- The public business is entrusted to the agent role to realize the division of business
- When the public business is expanded, it is convenient for centralized management
- A dynamic agent class represents an interface, which is generally a corresponding type of business
- A dynamic proxy class can proxy multiple classes as long as it implements the same interface
2.1 initial understanding
Instead of writing a proxy role, let him generate it himself.
package com.hxl.demo03; public class Host implements Rent{ public void rent() { System.out.println("The landlord wants to rent a house"); } }
package com.hxl.demo03; //Rent a house public interface Rent { public void rent(); }
generation reason of class \textcolor{orange} {proxy class} Proxy class
package com.hxl.demo03; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //This class will be used to automatically generate proxy classes later public class ProxyInvocationHandler implements InvocationHandler { //Proxy interface private Rent rent; public void setRent(Rent rent) { this.rent = rent; } //Generated proxy class public Object getProxy(){ Object o = Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this); return o; } //Process the proxy instance and return the result public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); //The essence of dynamic agent is to use reflection mechanism Object result = method.invoke(rent, args); fare(); return result; } public void seeHouse(){ System.out.println("The agent showed me the house"); } public void fare(){ System.out.println("Lease contract"); } }
measure try : \textcolor{orange} {test:} Test:
package com.hxl.demo03; public class Client { public static void main(String[] args) { //Real role Host host = new Host(); //Agent role: not now ProxyInvocationHandler pih = new ProxyInvocationHandler(); //Handle the interface object we want to call by calling the program processing role pih.setRent(host); //Get proxy class Rent proxy = (Rent) pih.getProxy();//The proxy here is generated dynamically. We didn't write it proxy.rent(); } }
2.2 further understanding
We make it into a formula similar to. Make it live and intelligent
Agent:
package com.hxl.demo04; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //This class will be used to automatically generate proxy classes later public class ProxyInvocationHandler implements InvocationHandler { //Proxy interface //Make it alive here private Object target; public void setTarget(Object target) { this.target = target; } //Generated proxy class public Object getProxy(){ Object o = Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); return o; } //Process the proxy instance and return the result public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //It can be written to death, such as log.add(); But it's not intelligent, so we have to enliven it log(method.getName()); //The essence of dynamic agent is to use reflection mechanism Object result = method.invoke(target, args); return result; } public void log(String msg){ System.out.println("Yes" + msg + "method"); } }
Test:
package com.hxl.demo04; import com.hxl.demo02.UserService; import com.hxl.demo02.UserServiceImpl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class Client { public static void main(String[] args) { //Real role UserServiceImpl userService = new UserServiceImpl(); //Agent role. non-existent ProxyInvocationHandler pih = new ProxyInvocationHandler(); //Sets the object to proxy pih.setTarget(userService); //Dynamically generate proxy classes UserService proxy = (UserService) pih.getProxy(); proxy.add(); } }