SpringAOP技术学习(4种技术总结)---Day4
2017-08-23 11:07
375 查看
本篇博客知识点
1.AOP的第四种技术:POJO+标签方式实现切面2.Spring的四种技术总结
AOP的第四种技术:POJO+标签方式实现切面
第四种技术真的非常非常简单!!!
你只要写一个完全独立的类,非常简单的类。
Myadvice
package cn.hncu2.V4; public class Myadvice { public void aa(){ System.out.println("Pojo第四中拦截AOP技术展示"); } }
这是你需要拦截的类
Person
/** * @author<a href="mailto:953801304@qq.com">胡龙华</a> */ public class Person { public void run(){ System.out.println("I'm running!"); } public void Hello(){ System.out.println("Hello,Spring!"); } }
主要核心的就是几个标签
v4.xml 当然你要导spring的包~ 前面讲过
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="muadice" class="cn.hncu2.V4.Myadvice"></bean> <aop:config> <aop:aspect ref="muadice"> <aop:before method="aa" pointcut="execution( void cn..Person.*(..) )"/> </aop:aspect> </aop:config> <bean id="p" class="cn.hncu2.V4.Person"></bean> </beans>
下面是测试代码和结果
第一种技术:最底层的方式实现AOP技术拦截,纯Java方式和XML方式
/** * @author<a href="mailto:953801304@qq.com">胡龙华</a> */ @Test public void t1(){ //切面=切点+通知 Advisor = cut + advice // 1.创建一个原型对象 Person p = new Person(); // 2.实现代理类工厂 ProxyFactoryBean factory = new ProxyFactoryBean(); //3.实现原型对象,代理目标 factory.setTarget(p); //4.声明切点:就是说你要来拦截原型对象的哪些方法 JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut(); //5.设置切点的正则:用正则表达式来设置拦截所有带run的方法 pointcut.setPattern(".*run.*"); //6.定义通知: 设定方法执行前栏、还是后栏还是都拦截(环绕栏) Advice advice = new MethodInterceptor() { //环绕栏 @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("前面拦拦"); Object obj = invocation.proceed(); System.out.println("后面拦截"); return obj; } }; //7.声明切面 : Advisor = pointcut + advice Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice); //8.把切面设置到代理工厂里:进厂子干活 factory.addAdvisor(advisor); //9.代理工厂生产代理后的对象 Person p2 = (Person) factory.getObject(); //测试 p2.run(); p2.Hello();
对于的XML方式—可以简化
<!-- 1.创建一个原型对象--> <bean id="p" class="cn.hncu2.v1.Person"/> <!-- 2.实现代理类工厂 --> <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 3.实现原型对象,代理目标 --> <property name="target" ref="p"/> <!-- 8.把切面设置到代理工厂里:进厂子干活 --> <property name="interceptorNames"> <list> <value>advisor</value> </list> </property> </bean> <!-- 4.声明切点:就是说你要来拦截原型对象的哪些方法 --> <bean id="pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <!-- 5.设置切点的正则:用正则表达式来设置拦截所有带run的方法 --> <property name="pattern" value=".*run.*"/> </bean> <!-- 6.定义通知: 设定方法执行前栏、还是后栏还是都拦截(环绕栏) --> <!-- 因为Java是实习的是匿名内部类,那么我们就自己写一个类就好了 --> <bean id="advice" class="cn.hncu2.v1.AroundAdvice"/> <!-- 7.声明切面 : Advisor = pointcut + advice--> <bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="pointcut" ref="pointcut"/> <property name="advice" ref="advice"></property> </bean>
第二种技术:核心与第一种相比是加入了切点语言,把拦截做得强大
纯Java方式底层代码
Person p = new Person(); ProxyFactoryBean factory = new ProxyFactoryBean(); factory.setTarget(p); AspectJExpressionPointcut cut = new AspectJExpressionPointcut(); cut.setExpression("execution( void cn.hncu2.v2.Person.run() )"); // 设置切点的表达式---切点语言 // cut.setExpression("execution( void cn.hncu.v2.Person.run() )"); // 写死的 Advice advice = new MethodInterceptor() { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("---------"); Object obj = invocation.proceed(); System.out.println("---------"); return obj; } }; Advisor advisor = new DefaultPointcutAdvisor(cut,advice); factory.addAdvisor(advisor); Person p2 = (Person) factory.getObject(); p2.run(); p2.Hello();
也可以用XML 方式实现,更简洁
<!-- 自动代理 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean> <bean id="advisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor"> <property name="expression" value="execution(void cn.hncu2.v2.Person.run() )"/> <property name="advice"> <bean class="cn.hncu2.v2.AroundAdvice"></bean> </property> </bean> <bean id="p" class="cn.hncu2.v2.Person"></bean>
第三种技术:核心思想和前面两是一样的都是 实现切面=切点+通知这个公式,区别在于他是通过注解+XML的方式实现
一个通过注解实现的切面
package cn.hncu2.v3; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; // 公式: 切面 = 切点 + 通知 @Aspect // 类名字前加@Aspect public class Myadvice { //切点的两种形式 //第一种形式: 把用字符表示切点---放在成员变量上 private final String Cut ="execution( * cn..Person.*(..) ) )"; //第二种形式: 注释@Poincut---放在成员方法上 @Pointcut(value="execution( * cn..Person.*(..) )") //@Pointcut中的value属性来指定切点的表达式----用aspectj切点语言 public void aa(){ //该方法没别的功能,就是为了让@Pointcut有个寄居的地方,同时也用于标识该注解 } @Before(Cut) // before通知+第一种形式切点 public void before1(){ System.out.println("@Before拦截"); } //通知:必须加载函数方法名字上面, 参数JoinPoint jp 可选 (@Around为必选) @Before(value = "aa()")// before通知+第二种形式切点 public void before2(){ System.out.println("@Before方法拦截"); } @After(value = "aa()")// After通知+第二种形式切点 public void After2(){ System.out.println("@After拦截"); } @Around(value = "aa()")// After通知+第一种形式切点 public Object Around1(ProceedingJoinPoint p) throws Throwable{ System.out.println("@Around前拦截"); Object res = p.proceed(); //放行 System.out.println("@Around后拦截"); return res; } @AfterReturning(value = "aa()") public void AfterReturning(){ System.out.println("函数正常返回未出异常时执行"); } @AfterThrowing(value = "aa()") public void AfterThrowing(){ System.out.println("函数出现异常时候执行"); } }
添加到bean容器就可以使用了
<!-- 自动代理的标签 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- 注解式前面 --> <!-- <bean class="cn.hncu2.v3.Myadvice"></bean> --> <bean class="cn.hncu2.v3.Myadvice2"></bean> <bean id="p" class="cn.hncu2.v3.Person"></bean>
第四种技术:是通过存标签方式实现 核心也是切面=切点+通知
一个简单的类
public class Myadvice { /** * @author<a href="mailto:953801304@qq.com">胡龙华</a> */ public void aa(){ System.out.println("Pojo第四中拦截AOP技术展示"); } }
把前面那个类的方式 用作切面
<bean id="muadice" class="cn.hncu2.V4.Myadvice"></bean> <aop:config> <aop:aspect ref="muadice"> <aop:before method="aa" pointcut="execution( void cn..Person.*(..) )"/> </aop:aspect> </aop:config> <bean id="p" class="cn.hncu2.V4.Person"></bean>
四种技术是从第一种慢慢演变的第四种的,我学习的时候是从第一种开始学,更好的理解他里面的思想,用的话用第四种会更加轻松,简单
相关文章推荐
- spring aop技术 学习总结
- ITCAST视频-Spring学习笔记(使用JDK中的Proxy技术实现AOP功能)
- Spring AOP基础(Spring 3.x企业应用开发实战第六章)学习总结
- Spring学习总结(15)——Spring AOP 拦截器的基本实现
- SpringAOP技术学习---Day1
- Spring学习总结——Spring实现AOP的多种方式
- Spring.NET AOP技术学习
- Spring学习(十三)aop技术理解与使用
- spring学习总结(十):基于 XML 的配置AOP
- 框架学习—Spring的IOC容器之注解方式与AOP技术
- Spring学习总结(15)——Spring AOP 拦截器的基本实现
- Spring学习总结(16)——Spring AOP实现执行数据库操作前根据业务来动态切换数据源
- Spring学习总结——Spring实现AOP的多种方式
- Spring学习总结——Spring实现AOP的多种方式
- Spring 4 官方文档学习(七)核心技术之Spring AOP APIs
- Spring学习总结(16)——Spring AOP实现执行数据库操作前根据业务来动态切换数据源
- Spring学习总结(三)——Spring实现AOP的多种方式
- Spring学习总结7(AOP-基于XML)
- Spring IOC及AOP学习总结
- 技术总结 (三)--Spring aop