新手学习笔之使用手动代理实现aop编程
1.AOP
1.1概述
1)在软件作业中,AOP为Aspect Oriented Programming的缩写,意为面向切面编程。
2)AOP是OOP编程的延续,是软件开发中的一个热点,是Spring框架中重要的内容。
3)利用AOP可以对业务逻辑的各个部分进行隔离,从而达到降低逻辑之间的耦合性。
4)AOP采取了横向编程机制,取代了传统的纵向继承体系。
5)AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入
1.2实现原理
aop底层是通过代理实现的。
接口+实现类:Spring采用jdk动态代理Proxy
实现类:Spring采用cglib字节码增强
1.3相关术语
1.target:目标类,需要被代理的类,比如UserService
2.Joinpoint(接入点):所谓链接点是指那些可能被拦截的方法。例如:所有的方法
3.Pointcut切入点:已经被增强的连接点,比如:add()方法
4.advice通知/增强,增强代码。例如:after、before
5.Weaving(织入):是指把增强的advice应用到目标对象target来创建新的代理对象proxy的过程
6.proxy 代理类
7. Aspect(切面): 是切入点pointcut和通知advice的结合
一个线是一个特殊的面。
一个切入点和一个通知,组成成一个特殊的面。
1.4手动代理实现AOP
1.4.1
目标类
package oyb.service; public interface UserService { public void add(); public void delete(); public void update(); }
package oyb.service.impl; import oyb.service.UserService; public class UserServiceImpl implements UserService { @Override public void add() { System.out.println("添加用户。。。。。"); } @Override public void delete() { System.out.println("删除用户。。。。。"); } @Override public void update() { System.out.println("更新用户。。。。。"); } }
切面类
package oyb.aspect; public class MyAspect { public void before(){ System.out.println("开启事务"); } public void after(){ System.out.println("提交事务"); } }
工厂类
package oyb.factory; import oyb.aspect.MyAspect; import oyb.service.UserService; import oyb.service.impl.UserServiceImpl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class MyBeanFactory { public static UserService createUserService(){ //目标类 final UserService userService = new UserServiceImpl(); //2.切面类 final MyAspect aspect = new MyAspect(); //3代理类 将目标类和切面类进行结合 UserService proxyService = (UserService) Proxy.newProxyInstance(MyBeanFactory.class.getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //执行前 aspect.before(); //放行 Object obj = method.invoke(userService, args); //执行后 aspect.after(); return obj; } }); return proxyService; } }
测试类
package oyb.test; import org.junit.Test; import oyb.factory.MyBeanFactory; import oyb.service.UserService; public class test { @Test public void test(){ UserService userService = MyBeanFactory.createUserService(); userService.add(); } }
测试结果
通过调试可以知道userService是一个代理类
1.4.2cglib 增强字节码
- 没有接口只有实现类
-
采用字节码增强框架 cglib,在运行时 创建目标类的子类,从而对目标类进行增强。
工厂类如下:
package oyb.factory; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import oyb.aspect.MyAspect; import oyb.service.UserService; import oyb.service.impl.UserServiceImpl; import java.lang.reflect.Method; public class MyBeanFactory2 { public static UserService createUserService(){ //目标类 final UserService userService = new UserServiceImpl(); //2.切面类 final MyAspect aspect = new MyAspect(); //3.cglib核心 Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(userService.getClass()); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { aspect.before(); //执行目标类的方法,目标类和代理类是父子关系 Object obj = methodProxy.invokeSuper(o, objects); aspect.after(); return obj; } }); UserServiceImpl proxyService = (UserServiceImpl) enhancer.create(); return proxyService; } }
测试结果: