云虚服务器网站建设,国外购物网站建设,不备案的网站可以做竞价吗,新手开公司怎么找项目主要内容#xff1a;
了解Spring AOP的概念及其术语熟悉Spring AOP的JDK动态代理熟悉Spring AOP的CGLib动态代理掌握基于XML的AOP实现掌握基于注解的AOP实现AOP用官方话来说#xff1a;
AOP即面向切面编程。和OOP#xff08;面向对象编程#xff09;不同#xff0c;AOP主…主要内容
了解Spring AOP的概念及其术语熟悉Spring AOP的JDK动态代理熟悉Spring AOP的CGLib动态代理掌握基于XML的AOP实现掌握基于注解的AOP实现AOP用官方话来说
AOP即面向切面编程。和OOP面向对象编程不同AOP主张将程序中相同的业务逻辑进行横向隔离并将重复的业务逻辑抽取到一个独立的模块中以达到提高程序可重用性和开发效率的目的。 在传统的业务处理代码中通常都会进行事务处理、日志记录等操作。虽然使用OOP可以通过组合或者继承的方式来达到代码的重用但如果要实现某个功能如日志记录)同样的代码仍然会分散到各个方法中。
我在举个例子
为什么要使用aop我们做一个后台系统除了登录注册功能不用用户验证其他页面都需要用户验证写的页面越多这些代码重复率高你还得写这个时候我们把相同的功能给抽离出来用aop来统一处理.aop是一种思想spring aop是一个框架.是aop思想的实现
现在假如订单系统中有添加订单信息、更新订单信息和删除订单信息3个方法这3个方法中都包含事务管理业务代码订单系统的逻辑如图所示。 由订单系统可知添加订单信息、修改订单信息、删除订单信息的方法体中都包含事务管理的业务逻辑这就带来了一定数量的重复代码并使程序的维护成本增加。基于AOP可以为此类问题提供解决方案AOP可以将事务管理的业务逻辑从这三个方法体中抽取到一个可重用的模块进而降低横向业务逻辑之间的耦合减少重复代码。AOP的使用使开发人员在编写业务逻辑时可以专心于核心业务而不用过多地关注其他业务逻辑的实现不但提高了开发效率又增强了代码的可维护性。 除了统⼀的⽤户登录判断之外AOP 还可以实现
统⼀⽇志记录统⼀⽅法执⾏时间统计统⼀的返回格式设置统⼀的异常处理事务的开启和提交等也就是说使⽤ AOP 可以扩充多个对象的某个能⼒所以 AOP 可以说是 OOPObject Oriented Programming⾯向对象编程的补充和完善。
AOP术语
AOP并不是一个新的概念AOP中涉及很多术语如切面、连接点、切入点、通知/增强处理、目标对象、织入、代理和引介等下面针对AOP的常用术语进行简单介绍。 切面是指关注点形成的类关注点是指类中重复的代码)通常是指封装的、用于横向插入系统的功能类如事务管理、日志记录等)。在实际开发中该类被Spring容器识别为切面需要在配置文件中通过bean元素指定。连接点是程序执行过程中某个特定的节点例如某方法调用时或处理异常时。在Spring AOP中一个连接点通常是一个方法的执行。当某个连接点满足预先指定的条件时AOP就能够定位到这个连接点在连接点处插入切面该连接点也就变成了切入点。通知/增强处理就是插入的切面程序代码。可以将通知/增强处理理解为切面中的方法它是切面的具体实现。将切面代码插入到目标对象上从而生成代理对象的过程。织入可以在编译时类加 载时和运行时完成。在编译时进行织入就是静态代理而在运行时进行织入则是动态代理。目标对象是指被插入切面的方法即包含主业务逻辑的类对象。或者说是被一个或者多个切面所通知的对象。引介是一种特殊的通知它为目标对象添加一些属性和方法。这样即使一个业务类原本没有实现某一个接口通过AOP的引介功能也可以动态地为该业务类添加接口的实现逻辑让业务类成为这个接口的实现类。将通知应用到目标对象之后程序动态创建的通知对象就称为代理。代理类既可能是和原类具有相同接口的类也可能就是原类的子类可以采用调用原类相同的方式调用代理类。
一个连接点可以不是切入点但是一个切入点一定是一个连接点 Spring AOP的实现机制
熟悉JDK动态代理能够说出JDK动态代理的机制
默认情况下Spring AOP使用JDK动态代理JDK动态代理是通过 java.lang.reflect.Proxy类实现的可以调用Proxy类的newProxyInstance()方法创建代理对象。JDK动态代理可以实现无侵入式的代码扩展并且可以在不修改源代码的情况下增强某些方法。 案例演示Spring中JDK动态代理的实现过程
实现版本一 package cn.hdc.demo1.entity;import cn.hdc.demo1.dao.UserDao;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** JDK代理类*/
public class MyProxy implements InvocationHandler {//声明目标类接口private UserDao userDao;//创建代理方法public Object createProxy(UserDao userDao) {this.userDao userDao;// 1.classLoader - 类加载器ClassLoader classLoader MyProxy.class.getClassLoader();// 2.classes - 被代理对象实现的所有接口Class[] classes userDao.getClass().getInterfaces();// 3.使用代理类进行增强返回的是代理对象 this - 表示代理类JdkProxy本身。return Proxy.newProxyInstance(classLoader, classes, this);}/** 所有动态代理类的方法调用都会交由invoke()方法去处理* proxy 被代理的对象* method 将要被执行的方法信息反射* args 执行方法时需要的参数*/Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 创建切面对象MyAspect myAspect new MyAspect();// 前增强myAspect.check_permission();// 在目标类上调用方法并传入参数Object obj method.invoke(userDao, args);// 后增强myAspect.log();return obj;}
}运行结果 实现版本二 package cn.hdc.component;public class MyAspect {public void check_permission() {System.out.println(模拟检查权限。。。);}public void log() {System.out.println(模拟日志输入输出);}
}package cn.hdc.component;import cn.hdc.dao.UserDao;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class MyProxy implements InvocationHandler {private UserDao userDao;public Object createProxy(UserDao userDao) {this.userDao userDao;//创建jdk的动态代理对象需要三个参数类加载器被代理对象实现的接口处理器增强功能的具体实现)ClassLoader classLoader MyProxy.class.getClassLoader();Class?[] interfaces userDao.getClass().getInterfaces();//创建动态代理对象Object proxy Proxy.newProxyInstance(classLoader, interfaces, this);return proxy;}/*** param proxy 代理对象本身* param method 将要增强的方法* param args 方法的参数* return* throws Throwable*/Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//创建增强类对象MyAspect myAspect new MyAspect();myAspect.check_permission();//保证原有功能的执行Object obj method.invoke(userDao, args);//日志增强myAspect.log();return null;}
}CGLib动态代理
JDK动态代理存在缺陷它只能为接口创建代理对象当需要为类创建代理对象时就需要使用CGLib (Code Generation Library)动态代理CGLib动态代理不要求目标类实现接口它采用底层的字节码技术通过继承的方式动态创建代理对象。Spring的核心包已经集成了CGLib所需要的包所以开发中不需要另外导入JAR包。
实现版本一 package cn.hdc.demo2.entity;import cn.hdc.demo1.entity.MyAspect;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;// 代理类
public class CglibProxy implements MethodInterceptor {// 代理方法public Object createProxy(Object target) {// 创建一个动态类对象Enhancer enhancer new Enhancer();// 确定需要增强的类设置其父类enhancer.setSuperclass(target.getClass());// 添加回调函数enhancer.setCallback(this);// 返回创建的代理类return enhancer.create();}/*** proxy CGlib根据指定父类生成的代理对象* method 拦截的方法* args 拦截方法的参数数组* methodProxy 方法的代理对象用于执行父类的方法*/public Object intercept(Object proxy, Method method, Object[] args,MethodProxy methodProxy) throws Throwable {// 创建切面类对象MyAspect myAspect new MyAspect();// 前增强myAspect.check_permission();// 目标方法执行Object obj methodProxy.invokeSuper(proxy, args);// 后增强myAspect.log();return obj;}
}运行结果 实现版本二 package cn.hdc.entity;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class MyCglibProxy implements MethodInterceptor {public Object createProxy(Object object) {Enhancer enhancer new Enhancer();enhancer.setSuperclass(object.getClass());enhancer.setCallback(this);return enhancer.create();}/*** 增强功能的具体实现** param o 代理对象本身* param method 被代理的方法* param objects 方法需要的参数* param methodProxy 代理后的方法* return* throws Throwable*/Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {MyAspect myAspect new MyAspect();myAspect.check_permission();//保证原有功能的执行Object res methodProxy.invokeSuper(o, objects);myAspect.log();return res;}
}基于xml的Aop实现
基于注解的Aop实现