Write before:
Then record your Spring learning journey. If you don't understand it, it is recommended to read it first Previous blog posts , detailed codes can be found in My Gitee warehouse SSM learning Clone download learn to use!
1.9 AOP
1.9.1 AOP introduction
1.9.1.1 concept
It is the acronym of Aspect Oriented Programming, that is, aspect programming. It is a unified maintenance technology to realize program functions through precompiled mode and runtime dynamic agent! It is a continuation of OOP(Object Oriented Programming) and a derived paradigm of functional programming.
1.9.1.2 purpose
AOP can isolate each part of business logic, reduce the coupling between each part of business logic, improve the reusability of program, and greatly improve the efficiency of development!
1.9.1.3 advantages and functions
1.9.1.4 bottom layer implementation
Spring provides a dynamic proxy implementation! During operation, spring dynamically generates proxy objects through dynamic proxy. When it executes, it performs function enhancement intervention, and then calls the target object method to achieve the target!
1.9.1.5 dynamic agent technology
1.9.1.5.1 JDK agent (interface based)
The target object must have an interface to use. The generated proxy object is based on the interface. The proxy object has the method of the target object, as shown in the figure!
1.9.1.5.2 cglib proxy (based on parent class)
The target object is equivalent to the parent object and the proxy object is equivalent to the child object. Note that it is not an inheritance, but a dynamically generated object!
1.9.2 underlying implementation of dynamic proxy code
1.9.2.1 project preparation
Build a simple project according to [[#1 2 spring project IntelliJ IDEA 2020 1 Ultimate Edition]] and configure the missing directory, as shown in the figure below
1.9.2.2 JDK dynamic agent
- Create a new Tearget interface and its implementation class in the jdk directory and rewrite the method, as shown in the figure
- Create a new class in the same directory, and write the enhanced execution methods before and after, as shown in the figure
1.9.2.3 Cglib dynamic agent
- Add the spring context resource dependency in the pom file, which contains its cglib resource package, as shown in the figure
- Copy the execution enhancement class under the JDK package, and create a new target object target class, as shown in the figure
1.9.2.4 testing JDK agent
Create a new test class under the test directory for testing. The code is as follows:
public class test { @Test public void testJDKProxy() { final TargetInterfaceImpl target = new TargetInterfaceImpl(); // Get enhancement object final EnhanceRunning enhanceRunning = new EnhanceRunning(); // The return value is the proxy object generated for the dynamic proxy TargetInterface targetInterface = (TargetInterface) Proxy.newProxyInstance( // Target object class loader target.getClass().getClassLoader(), // An array of interface bytecode objects with the same target object target.getClass().getInterfaces(), new InvocationHandler() { // The invoke method is executed by default when the proxy object method is executed @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Add before execution enhanceRunning.before(); // Execution target method method.invoke(target, args); // Post execution enhancement enhanceRunning.after(); return null; } } ); // Call proxy object method targetInterface.testMessage(); } }
If the result is shown in the figure, it will be successful!
1.9.2.5 testing the Cglib agent
The code is similar to testing JDK dynamic agent, but it is not required to master it. You can understand it as follows:
@Test public void testCglib() { // Target object final Target target = new Target(); // Enhanced object final EnhanceRunning enhanceRunning = new EnhanceRunning(); // Create intensifier Enhancer enhancer = new Enhancer(); // Set parent (target) enhancer.setSuperclass(Target.class); // Set callback enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { // Pre execution enhancement enhanceRunning.before(); // Execution target method Object object = method.invoke(target,objects); // Post execution enhancement enhanceRunning.after(); return object; } }); // Generate proxy object Target proxy = (Target) enhancer.create(); proxy.testMessage(); }
If the result is shown in the figure, it will be successful!