建设部的网站首页,网站换空间 怎么下载,商务平台网站建设合同,wordpress 主题前言
本文不仅介绍Spring中AOP的几种实现方式。还整体介绍一下#xff1a;静态代理、JDK API动态代理和CGLIB动态代理
文中示例的代码地址#xff1a;
GitHubhttps://github.com/Web-Learn-GSF/Java_Learn_Examples父工程Java_Framework_Spring
静态代理、动态代理*2
他…前言
本文不仅介绍Spring中AOP的几种实现方式。还整体介绍一下静态代理、JDK API动态代理和CGLIB动态代理
文中示例的代码地址
GitHubhttps://github.com/Web-Learn-GSF/Java_Learn_Examples父工程Java_Framework_Spring
静态代理、动态代理*2
他人文章参考
这三个示例可以直接看文章https://segmentfault.com/a/1190000011291179#item-4
自己编写示例
下边示例是自己写的有空再补充吧
示例在上述工程的具体Module里面静态代理AOP_0_Static_ProxyJDK API动态代理暂无CGLIB动态代理暂无
三种方式优缺点对比
静态代理 特点实现简单只需要代理对象对目标对象封装即可实现功能增强。 缺点静态代理只能为一个目标对象服务目标对象过多就会产生很多的代理类 这个缺点存疑。如果将目标对象实例化在代理类中即一个静态代理类代理一个目标对象那肯定是目标对象越多代理类就越多。但如果通过在代理对象中定义set方法就可以实现一个代理类代理同一个接口下的多个目标对象就没有这个缺点了。
动态代理 | JDK API
特点动态代理必须实现InvocationHandler接口且要求目标对象有接口实现。通过反射代理方法实现对目标对象的增强缺点目标对象必须要有接口不然无法应用
动态代理 | CGLIB
特点无需目标对象有接口实现通过生成类字节码实现代理比反射稍快不存在性能问题。缺点代理类需要继承目标对象即目标对象不能被final修饰
Spirng中实现AOP
Spring中实现AOP有如下几种方式
实现方式在上述工程中的Module位置xml 实现Spring的APIAOP_1_Xml_SpringAPIxml 自定义类AOP_2_Xml_CustomClassxml 注解 自定义类AOP_3_Xml_Annotation注解 自定义类暂空
下边展示每种实现方式里面的关键部分代码。
xml 实现Spring的API
public class LogAfterMethod implements AfterReturningAdvice {Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println(AOP后置通知 在 target.getClass().getName() 的 method.getName() 方法调用后执行。目标对象-方法-参数都可以获取到);}
}public class LogBeforeMethod implements MethodBeforeAdvice {Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(AOP前置通知 在 target.getClass().getName() 的 method.getName() 方法调用前执行。目标对象-方法-参数都可以获取到);}
}?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd!-- 注册bean --bean iduserService classGSF.Example.Service.UserServiceImpl /bean idlogBefore classGSF.Example.Log.LogBeforeMethod /bean idlogAfter classGSF.Example.Log.LogAfterMethod/!-- Aop的设置--aop:config!-- 切入点--aop:pointcut idpointcut expressionexecution(* GSF.Example.Service.UserServiceImpl.*(..))/!-- 执行前置通知--aop:advisor advice-reflogBefore pointcut-refpointcut /aop:advisor advice-reflogAfter pointcut-refpointcut //aop:config
/beansxml 自定义类
package GSF.Example.Log;public class CustomLogClass {public void before(){System.out.println(---------基于XML自定义类方式实现前置通知:方法执行前---------);}public void after(){System.out.println(---------基于XML自定义类方式实现后置通知:方法执行前---------);}
}
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd!-- 注册bean --bean iduserService classGSF.Example.Service.UserServiceImpl /bean idcustomLogClass classGSF.Example.Log.CustomLogClass /!--Aop的设置--aop:config!-- 切入点--aop:aspect refcustomLogClassaop:pointcut idpointcut expressionexecution(* GSF.Example.Service.UserServiceImpl.*(..))/aop:before methodbefore pointcut-refpointcut/aop:after methodafter pointcut-refpointcut //aop:aspect/aop:config
/beansxml 注解 自定义类
package GSF.Example.Log;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;Aspect
public class AnnotationClass {Before(execution(* GSF.Example.Service.UserServiceImpl.*(..)))public void before(){System.out.println(---------基于注解方式实现前置通知:方法执行前---------);}After(execution(* GSF.Example.Service.UserServiceImpl.*(..)))public void after(){System.out.println(---------基于注解方式实现后置通知方法执行后---------);}Around(execution(* GSF.Example.Service.UserServiceImpl.*(..)))public void around(ProceedingJoinPoint jp) throws Throwable{System.out.println(环绕通知环绕前);System.out.println(jp.getSignature());// 执行目标方法Object proceed jp.proceed();System.out.println(proceed);System.out.println(环绕通知环绕后);}
}?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd!-- 注册bean --bean iduserService classGSF.Example.Service.UserServiceImpl /bean idannotationPointcut classGSF.Example.Log.AnnotationClass /!-- 自动代理 --aop:aspectj-autoproxy//beans注解 自定义类
在上述xml注解自定义类的实现方式中xml文件的作用已经弱化为只有注册bean 开启允许注解实现AOP
只需要通过注解取代上述两种方法就可以抛弃xml文件完成仅注解自定义类实现AOP。
有空再写。
理解AOP中的概念
通过该参考文章理解AOP中的相关概念https://www.cnblogs.com/aduner/p/14656427.html
接下来相关概念的解释也都用上述文章中的示例来讲。
概念 | 连接点
Spring是方法级的AOP一般对某个方法进行增强。选择的这个方法就是连接点的意思这里选择的切入点就是Landlord类的service()方法
Component
public class Landlord {public void service() {System.out.println(签合同);System.out.println(收钱);}
}概念 | 切面
切面可以理解一个拦截器在切面上我们对连接点的前边、后边进行方法增强。切面对应一个类也是Spring中的一个Bean这里选择的切面就是Broker类通过Aspect注解定义该类为一个切面
Component
Aspect
class Broker {Before(execution(* com.aduner.demo03.pojo.Landlord.service()))public void before(){System.out.println(带租客看房);System.out.println(谈钱);}After(execution(* com.aduner.demo03.pojo.Landlord.service()))public void after(){System.out.println(给钥匙);}
}概念 | 切入点 切面中的方法都对一个连接点进行增强有些重复的代码。可以定义一个切入点。 切面中的方法想要对某个切入点进行增强就使用该切入点 上述代码可以修改为
Component
Aspect
class Broker {// 切入点Pointcut(execution(* com.aduner.demo03.pojo.Landlord.service()))public void pointcut() {}// 使用上述切入点Before(pointcut())public void before() {System.out.println(带租客看房);System.out.println(谈钱);}After(pointcut())public void after() {System.out.println(给钥匙);}
}概念 | 通知、目标、代理、横切关注点
通知上述代码中已经体现。before()方法就是一个前置通知通过注解Before赋予该方法前置通知的功能目标Spring的AOP是对方法进行增强被增强的方法叫做连接点。那连接点所属的类就是目标代理Spring AOP的实现是动态代理会有一个代理对象代码中没有体现但这个概念好理解横切关注点又是一个宏观的概念。日志、安全、权限都可以认为是横切关注点。示例中的横切关注点可以理解为租房的准备工作
其余问题 多个切面如果不同切面的切点相同那就有多个切面需要规定每个切面的执行顺序 通知Advice的类别5种
通知类型连接点实现接口前置通知方法前org.springframework.aop.MethodBeforeAdvice后置通知方法后org.springframework.aop.AfterReturningAdvice环绕通知方法前后org.springframework.aop.MethodInterceptor异常抛出通知方法抛出异常org.springframework.aop.ThrowsAdvice引介通知类中增加新的方法属性org.springframework.aop.IntroductionInterceptor