Original link: https://blog.csdn.net/qq_38701478/article/details/82785541
Spring is said in many places to be a one-stop solution with IOC and AOP as the core, that is, a framework.The previous blogs explained in detail the principles of IOC implementation in Spring and how to manage the dependencies between objects, and manually implemented an IOC container through appropriate cases.So today, let's explain the principle of AOP and bring you all to implement an AOP manually.
Here's a review of AOP. The full name of AOP is Aspect Oriented Programming, which is Face Oriented Programming. In a previous blog, you have briefly explained the basic idea of AOP. Today, you will take you to implement an AOP manually.Of course, before this we need to understand the agent mode, in the previous section we will give you a brief introduction to the design mode.Today, let's take you with us as a new design mode - agent mode.
What is proxy mode?The so-called oral interpretation of agent mode is to find one type to do another type of things that should be done, like the intermediaries we meet when renting a house or looking for a job.Well, that's really not easy to understand. Let's take a look at the following cases. Let's write a program to demonstrate dynamic proxy.
Open eclipse and create a new project, as shown in the following image:
For demonstration purposes, I wrote the code into my last project.All you need to do is look under the aop_demo package.Okay, let's first define the interface in the dao layer, create a new UserDao interface, and define four basic ways to add or delete the lookup in that interface. The code is as follows:
public interface UserDao { public void save(); public void update(); public void delete(); public void find(); }
Next, write the implementation class for the interface, with the following code:
package aop_demo.dao; public class UserDaoImpl implements UserDao{ @Override public void save() { // TODO Auto-generated method stub System.out.println("Add User Executed---------"); } @Override public void update() { // TODO Auto-generated method stub System.out.println("Update user executed---------"); } @Override public void delete() { // TODO Auto-generated method stub System.out.println("Delete User Executed---------"); } @Override public void find() { // TODO Auto-generated method stub System.out.println("Query user executed---------"); } }
Okay, we've done the work at the dao level. As mentioned earlier, when we're huddled with databases, we need to start and commit transactions. To solve a lot of duplicate code, we can pull out the duplicate code. This idea is AOP thinking, which is face-to-face programming.Now let's simulate opening and committing transactions, and define a class Aspect under the service package with the following code:
package aop_demo.service; //Classes enhanced by methods public class Aspect { public void before() { System.out.println("[**********Open Transaction**********"); } public void after() { System.out.println("**********Submit Transaction**********]"); } }
You can see a simple simulation of the transaction in the above class.Equivalent to duplicate code extracted horizontally.It may be a little hard to understand, to recall the role of AOP, in Spring it provides face-to-face support, also known as SpringAOP, to encapsulate logic code that is not business related but is called together by business modules.Okay, the two ways here are to simulate extracting duplicate code.
Let's look at the next class, which is the core of this case, with the following code
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import aop_demo.dao.UserDao; import aop_demo.dao.UserDaoImpl; /** * * @author Scan * */ public class BeanFactory { public static UserDao getBean() { //Prepare target class final UserDao userDao = new UserDaoImpl(); //Create an Aspect object final Aspect aspect = new Aspect(); //Enhancement of target objects using proxy classes return (UserDao)Proxy.newProxyInstance(BeanFactory.class.getClassLoader(), new Class[] {UserDao.class},new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub //Front Enhancement aspect.before(); //Target Method Object object = method.invoke(userDao, args); //Post Enhancement aspect.after(); return object; } }); } }
First, the getBean method is equivalent to the IOC container in Spring and is used to provide an object. You need to know about the Proxy class here, which gives an explanation in the api document, as shown in the following figure:
From the diagram above, we know that the Proxy class is a class used to implement dynamic proxy. In this case, AOP is implemented by this technology. You can see that the above code is implemented by the newProxyInstance method in Proxy. Here is a list of parameters. The first parameter is the class loader of the proxy class.The second parameter is the bytecode object that needs to be enhanced, which is the target interface that the proxy class will enhance, because it supports enhancing multiple classes, so it can be an array of bytecode objects here, and the third parameter is the InvocationHandler object, which is the method that needs to be enhanced.The object has three parameters to accept, the first two being the enhancement method, and the second being the method of the target class, which is the method of the class that needs to be enhanced. Since multiple classes can be enhanced, an array of objects can be tried.Okay, the basic work is almost done.
The following class is the test class to see the effect of our manual implementation of Aop.
public class AOP_Test { @Test public void userDao() { UserDao userDao = new UserDaoImpl(); //Execution Method userDao.save(); userDao.delete(); userDao.update(); userDao.find(); } }
The results are as follows:
You can see that this is a normal way to create objects, call the methods of objects, and not enhance the methods. Let's try using dynamic proxy technology to enhance the methods. Okay, define a test method in the test class, the code is as follows:
@Test public void testAop() { //Get UserDao object UserDao userDao = BeanFactory.getBean(); //Execution Method userDao.save(); userDao.delete(); userDao.update(); userDao.find(); }
The results are as follows:
You can see that each method has been enhanced, which is a small case of AOP implemented manually for you today. Looking at these two methods carefully, you can see that the two methods are just different ways to get objects. There is a reason for writing this. Here is to simulate IO for you.C container, ok, I hope you can have a good look at the small cases in this blog, and in the next blog, you can use another way to implement AOP.
--------
Copyright Statement: This is an original article by CSDN blogger Skr_coder. It is reproduced in accordance with the CC 4.0 BY-SA copyright agreement. Please attach a link to the original source and this statement.
Original link: https://blog.csdn.net/qq_38701478/article/details/82785541