AOP面向切面编程的四种实现
2016-10-13 10:36
721 查看
一.AOP(面向切面编程)的四种实现分别为最原始的经典AOP、代理工厂bean(ProxyFacteryBean)和默认自动代理DefaultAdvisorAutoProxyCreator以及BeanNameAutoProxyCreator代理、Aspectj的注解和xml配置文件。
1.代理工厂bean(ProxyFacteryBean)的方式
1.1 接口(Interface)
1.2 接口的实现类
1.3 各种通知增强
1.3.1 前置增强
1.3.2 后置增强
1.3.3 环绕增强
1.3.4 异常增强
1.4 配置文件
1.5 测试类
2. 最原始的经典AOP
2.1 最基本分层模式dao、biz、service以及最后测试Test
2.1.1DAO层
2.1.2 BIZ层
2.1.3 AOP模块即service层
2.1.4 经典的配置文件
2.1.5 测试类
3. 然后就是Aspectj的注解以及xml配置文件的两种方式了。
3.1 Aspectj注解
3.1.1 接口和实现类
3.1.2 注解类Aspect
3.1.3 注解的配置文件
3.1.4 测试类
4. Aspectj的XML配置法,其他的基本都一样只要修改Aspectj增强类和配置文件就行了
4.1 Aspect增强类只需将那些注解消去即可
4.2 XML的配置文件会稍微会复杂一点,但大致的还是跟对原始的经典aop实现方式相同
好了,这就是AOP(面向切面编程)的四种实现方式了。希望你们看了之后能让你们对AOP面向切面编程思想有更深的了解。
1.代理工厂bean(ProxyFacteryBean)的方式
1.1 接口(Interface)
1 package cn.happy.interfaces; 2 3 public interface Advice { 4 5 public void fristMethod(); 6 7 public String secondMethod(); 8 }
1.2 接口的实现类
1 package cn.happy.impl; 2 3 import cn.happy.interfaces.Advice; 4 5 public class AdviceImpl implements Advice { 6 7 public void fristMethod() { 8 System.out.println("==fristMethod=="); 9 } 10 11 public String secondMethod() { 12 System.out.println("==secondMethod=="); 13 return "abc"; 14 } 15 16 }
1.3 各种通知增强
1.3.1 前置增强
1 package cn.happy.advice; 2 3 import java.lang.reflect.Method; 4 5 public class MethodBeforeAdvice implements 6 org.springframework.aop.MethodBeforeAdvice { 7 8 public void before(Method arg0, Object[] arg1, Object arg2) 9 throws Throwable { 10 System.out.println("==Before=="); 11 12 } 13 14 }
1.3.2 后置增强
1 package cn.happy.advice; 2 3 import java.lang.reflect.Method; 4 5 import org.springframework.aop.AfterReturningAdvice; 6 7 public class AfterReturningAdvie implements AfterReturningAdvice { 8 9 public void afterReturning(Object arg0, Method arg1, Object[] arg2, 10 Object arg3) throws Throwable { 11 System.out.println("==After=="); 12 13 } 14 15 }
1.3.3 环绕增强
package cn.happy.aroundadvice; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class MyInterceptor implements MethodInterceptor{ public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("==before=="); String result= (String)invocation.proceed(); System.out.println("==after=="); return result; } }
1.3.4 异常增强
package cn.happy.exception; import org.springframework.aop.ThrowsAdvice; public class MyException implements ThrowsAdvice { public void afterThrowing(Exception ex){ System.out.println("异常通知"); } }
1.4 配置文件
<?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: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/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 实现类的引入 --> <bean id="adviceimpl" class="cn.happy.impl.AdviceImpl"></bean> <!-- 前置增强 通知--> <bean id="advicebefore" class="cn.happy.advice.MethodBeforeAdvice"></bean> <!-- 后置增强 通知--> <bean id="adviceafter" class="cn.happy.advice.AfterReturningAdvie"></bean> <!-- 环绕增强 --> <bean id="around" class="cn.happy.aroundadvice.MyInterceptor"></bean> <!-- 关联 代理工厂bean ProxyFacteryBean 通知 --> <!--<bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="targetName" value="adviceimpl"></property> <property name="interceptorNames" value="advicebefore,adviceafter"></property> </bean>--> <!-- 环绕增强 代理工厂 顾问包装通知 --> <bean id="aroundserviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="adviceimpl"></property> <property name="interceptorNames" value="beforeadvisor"></property> </bean> <!-- 切面 通知 --> <bean id="beforeadvice" class="cn.happy.mymethodbefore.MyMethodBeforeAdvice"></bean> <!-- 顾问 包装advice --> <bean id="beforeadvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice" ref="beforeadvice"></property> <property name="mappedNames" value="fristMethod,secondMethod"></property> </bean> <!-- 顾问 包装advice 正则表达式--> <!--<bean id="beforeadvisor1" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="beforeadvice"></property> <property name="pattern" value=".*Method.*"></property> </bean>--> <!-- 默认自动代理 默认只找通知--> <!--<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>--> <!-- beanname自动代理 可以选择顾问或者通知--> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames" value="adviceimpl"></property> <property name="interceptorNames" value="beforeadvisor"></property> </bean> </beans>
1.5 测试类
package cn.happy.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.happy.interfaces.Advice; public class Test { /** * 通知的前置和后置测试 */ public static void main(String[] args) { //解析配置文件 ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); Advice advice= (Advice)ctx.getBean("adviceimpl"); //自动代理beanname的方式 advice.fristMethod(); advice.secondMethod(); } }
2. 最原始的经典AOP
2.1 最基本分层模式dao、biz、service以及最后测试Test
2.1.1DAO层
package cn.happy.dao; import cn.happy.entity.User; //接口 public interface UDao { //保存方法 public void save(User user); } //实现类 package cn.happy.dao; import cn.happy.entity.User; public class UserDaoImpl implements UDao{ public void save(User user) { System.out.println("保存成功"); } }
2.1.2 BIZ层
package cn.happy.biz; import cn.happy.entity.User; //业务接口 public interface UBiz { //保存方法 public void save2(User user); } //业务实现类 package cn.happy.biz; import cn.happy.dao.UDao; import cn.happy.entity.User; public class UserBiz implements UBiz{ //dao的对象 private UDao udao; public void save2(User user) { udao.save(user); } public UDao getUdao() { return udao; } public void setUdao(UDao udao) { this.udao = udao; } }
2.1.3 AOP模块即service层
package cn.happy.logger; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; //前置内容 public class LoggerBefore implements MethodBeforeAdvice { public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { System.out.println("save前置内容"); } } //后置内容 package cn.happy.logger; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class LoggerAfter implements AfterReturningAdvice{ public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable { System.out.println("save后置内容"); } }
2.1.4 经典的配置文件
<?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" 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-4.1.xsd"> <!-- 业务biz与dao接口对象的实现 --> <bean id="dao" class="cn.happy.dao.UserDaoImpl"></bean> <bean id="biz" class="cn.happy.biz.UserBiz"> <property name="udao" ref="dao"></property> </bean> <!-- 前置与后置内容的配置 --> <bean id="before" class="cn.happy.logger.LoggerBefore"></bean> <bean id="after" class="cn.happy.logger.LoggerAfter"></bean> <!-- aop的配置 --> <aop:config> <aop:pointcut expression="execution(public void save2(cn.happy.entity.User))" id="pointcut"/> <!-- 在切入点处插入增强处理、完成"织入" --> <aop:advisor advice-ref="before" pointcut-ref="pointcut"/> <aop:advisor advice-ref="after" pointcut-ref="pointcut"/> </aop:config> </beans>
2.1.5 测试类
package cn.happy.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.happy.biz.UBiz; import cn.happy.entity.User; public class AOPTest { public static void main(String[] args) { ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); UBiz ubiz=(UBiz)context.getBean("biz"); User user=new User(); ubiz.save2(user); System.out.println("save~ok"); } }
3. 然后就是Aspectj的注解以及xml配置文件的两种方式了。
3.1 Aspectj注解
3.1.1 接口和实现类
package cn.happy.impl; //接口 public interface AspectDao { public void add(); public void delete(); } //实现类 package cn.happy.impl; public class AspectjIpml implements AspectDao{ //添加 public void add() { System.out.println("==ADD=="); } //删除 public void delete() { System.out.println("==DELETE=="); } }
3.1.2 注解类Aspect
package cn.happy.aspectj; 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.Before; @org.aspectj.lang.annotation.Aspect public class Aspect { //前置增强 @Before(value="execution(public * *(..))") public void asBefore(){ System.out.println("这是前置增强"); } //后置增强 @AfterReturning(value="execution(public * *(..))") public void asAfterReturning(){ System.out.println("这是后置增强"); } //环绕增强 @Around(value="execution(public * *(..))") public void asAround(ProceedingJoinPoint pj){ System.out.println("这是环绕前置增强"); try { pj.proceed(); } catch (Throwable e) { //抓捕异常 e.printStackTrace(); } System.out.println("这是环绕后置增强"); } //异常增强 @AfterThrowing(value="execution(public * *(..))") public void asThorws(){ System.out.println("这是异常增强"); } //最终增强 @After(value="execution(public * *(..))") public void asAfter(){ System.out.println("这是最终增强"); } }
3.1.3 注解的配置文件
<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 目标对象 --> <bean id="aspectimpl" class="cn.happy.impl.AspectjIpml"></bean> <!-- 增强类 --> <bean id="aspectj" class="cn.happy.aspectj.Aspect"></bean> <!-- 扫描整个项目 关联注解类和实现类 --> <aop:aspectj-autoproxy /> </beans>
3.1.4 测试类
package cn.happy.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.happy.impl.AspectDao; public class AspectjTest { /** * 注解测试 */ public static void main(String[] args) { // 解析配置文件 ApplicationContext ctx = new ClassPathXmlApplicationContext( "applicationContext.xml"); AspectDao aspect = (AspectDao) ctx.getBean("aspectimpl"); aspect.add(); aspect.delete(); } }
4. Aspectj的XML配置法,其他的基本都一样只要修改Aspectj增强类和配置文件就行了
4.1 Aspect增强类只需将那些注解消去即可
package cn.happy.aspectj; import org.aspectj.lang.ProceedingJoinPoint; public class Aspect { //前置增强 public void asBefore(){ System.out.println("这是前置增强"); } //后置增强 public void asAfterReturning(){ System.out.println("这是后置增强"); } //环绕增强 public void asAround(ProceedingJoinPoint pj){ System.out.println("这是环绕前置增强"); try { pj.proceed(); } catch (Throwable e) { //抓捕异常 e.printStackTrace(); } System.out.println("这是环绕后置增强"); } //异常增强 public void asThorws(){ System.out.println("这是异常增强"); } //最终增强 public void asAfter(){ System.out.println("这是最终增强"); } }
4.2 XML的配置文件会稍微会复杂一点,但大致的还是跟对原始的经典aop实现方式相同
<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 目标对象 --> <bean id="aspectimpl" class="cn.happy.impl.AspectjIpml"></bean> <!-- 增强类 --> <bean id="aspectj" class="cn.happy.aspectj.Aspect"></bean> <!-- Aspectj的XML配置文件 --> <aop:config> <aop:pointcut expression="execution(public * *(..))" id="pointcut"/> <aop:aspect ref="aspectj"> <aop:before method="asBefore" pointcut-ref="pointcut"/> <aop:after-returning method="asAfterReturning" pointcut-ref="pointcut"/> <aop:after-returning method="asAround(org.aspectj.lang.ProceedingJoinPoint)" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans>
好了,这就是AOP(面向切面编程)的四种实现方式了。希望你们看了之后能让你们对AOP面向切面编程思想有更深的了解。
相关文章推荐
- spring AOP面向切面编程的四种实现方式
- Java实现AOP面向切面编程的实例教程
- JavaEE手写AOP实现,自动代理, AOP 面向切面的编程思想
- JavaScript实现AOP详解(面向切面编程,装饰者模式)
- CGLIB实现AOP代理的测试类,与Spring分离,加深对面向切面编程的理解
- spring学习笔记7--使用spring进行面向切面的(AOP)编程(1)注解方式实现
- idea 实现Spring讲解(Ioc-控制反转)/Aop(面向切面的编程)
- 面向切面编程AOP 在iOS中的实现
- spring_由XML实现AOP面向切面编程_实现动态代理
- spring_由注解实现AOP面向切面编程_实现动态代理
- Spring AOP的基本原理及面向切面编程的实现
- Spring面向切面编程——Spring实现AOP方式——通过Spring API实现
- 黑马程序员--Spring Aop 面向切面编程,实现前置通知
- js实现面向切面的编程(AOP)
- aop(面向切面)编程思想在spring框架下实现的配置方法
- js实现面向切面的编程(AOP)
- Spring面向切面编程——Spring实现AOP方式——通过注解实现
- Spring面向切面编程——Spring实现AOP方式——自定义类实现
- python 多个装饰器组合应用,实现面向切面之AOP编程
- Java实现AOP面向切面编程的实例教程