9-15 3,173 views
AOP(Aspect Oriented Programing,面向切面编程)用于在不侵入原有代码的基础上,为代码统一添加新功能,例如性能监控、日志记录、事务管理等。AOP的原理如图所示:
其中:
1)连接点(Jointpoint),表示方法执行的某个位置,如方法调用前、方法调用后、方法抛出异常等;
2)通知(Advice),表示需要在某个连接点加入的新功能,通知包括以下5种类型:Before advice,After returning advice,After throwing advice,After (finally) advice,Around advice;
3)切入点(Pointcut),用于描述某些类的某些方法;
4)切面(Aspect),通知和切入点组成切面,通过切面实现在指定类的指定方法上,加入通知。
Spring AOP的实现基于动态代理,有以下4种实现方式:
1)基于Aspect注解;
2)基于aop标签配置;
3)基于ProxyFactoryBean;
4)基于DefaultAdvisorAutoProxyCreator。
通过一个例子分别说明上述4种实现方式。例子中包含TestService接口及其实现TestServiceImpl,TestServiceImpl的test方法输出“execute test method”:
1 2 3 4 5 6 7 |
package com.magicwt.service; public interface TestService { public void test(); } |
1 2 3 4 5 6 7 8 9 10 11 |
package com.magicwt.service.impl; import com.magicwt.service.TestService; public class TestServiceImpl implements TestService { public void test() { System.out.println("execute test method"); } } |
main方法初始化Spring上下文,获取TestService实例,并执行test方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.magicwt; import com.magicwt.service.TestService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("context.xml"); TestService testService = (TestService) applicationContext.getBean("testService"); testService.test(); } } |
Spring上下文配置文件context.xml:
1 2 3 4 5 6 7 8 9 10 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="testService" class="com.magicwt.service.impl.TestServiceImpl"/> </beans> |
执行main方法,输出:
execute test method
以下通过Spring AOP,在test方法调用前和调用后,增加切面。
新建类TestAspect:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
package com.magicwt.aop; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; /** * 配置切面和组件 */ @Component @Aspect public class TestAspect { /** * 配置切入点,com.magicwt.service包下所有类的所有方法 */ @Pointcut("execution(* com.magicwt.service..*(..))") public void pointcut() {} /** * 方法调用前通知 */ @Before("pointcut()") public void before() { System.out.println("execute before advice"); } /** * 方法调用后通知 */ @After("pointcut()") public void after() { System.out.println("execute after advice"); } } |
context.xml修改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> <bean id="testService" class="com.magicwt.service.impl.TestServiceImpl"/> <!-- 扫描com.magicwt.aop包下的组件,进行初始化 --> <context:component-scan base-package="com.magicwt.aop"/> <!-- 根据注解自动创建代理,织入切面 --> <aop:aspectj-autoproxy /> </beans> |
执行main方法,输出:
execute before advice
execute test method
execute after advice
TestAspect:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.magicwt.aop; public class TestAspect { public void before() { System.out.println("execute before advice"); } public void after() { System.out.println("execute after advice"); } } |
context.xml修改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> <bean id="testService" class="com.magicwt.service.impl.TestServiceImpl"/> <bean id="testAspect" class="com.magicwt.aop.TestAspect"/> <aop:config> <!-- 配置切面 --> <aop:aspect ref="testAspect"> <!-- 配置切入点,com.magicwt.service包下所有类的所有方法 --> <aop:pointcut id="pointcut" expression="execution(* com.magicwt.service..*(..))"/> <!-- 配置方法调用前通知 --> <aop:before method="before" pointcut-ref="pointcut"/> <!-- 配置方法调用后通知 --> <aop:after method="after" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans> |
执行main方法,输出:
execute before advice
execute test method
execute after advice
新建类TestAdvice,实现接口MethodBeforeAdvice、AfterReturningAdvice,重写before、afterReturning方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.magicwt.aop; import org.springframework.aop.AfterReturningAdvice; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class TestAdvice implements MethodBeforeAdvice, AfterReturningAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("execute before advice"); } @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("execute after advice"); } } |
context.xml修改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="realTestService" class="com.magicwt.service.impl.TestServiceImpl"/> <bean id="testAdvice" class="com.magicwt.aop.TestAdvice"/> <!-- 配置切入点,com.magicwt.service包下所有类的所有方法 --> <bean id="pointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcut"> <property name="expression" value="execution(* com.magicwt.service..*(..))"/> </bean> <!-- 配置切面 --> <bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice" ref="testAdvice"/> <property name="pointcut" ref="pointcut"/> </bean> <!-- 创建代理,织入切面 --> <bean id="testService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="realTestService"/> <property name="interceptorNames" value="advisor" /> <property name="proxyInterfaces" value="com.magicwt.service.TestService" /> </bean> </beans> |
执行main方法,输出:
execute before advice
execute test method
execute after advice
与基于ProxyFactoryBean的实现相比,只需修改context.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="testService" class="com.magicwt.service.impl.TestServiceImpl"/> <bean id="testAdvice" class="com.magicwt.aop.TestAdvice"/> <!-- 配置切入点,com.magicwt.service包下所有类的所有方法 --> <bean id="pointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcut"> <property name="expression" value="execution(* com.magicwt.service..*(..))"/> </bean> <!-- 配置切面 --> <bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice" ref="testAdvice"/> <property name="pointcut" ref="pointcut"/> </bean> <!-- 通过DefaultAdvisorAutoProxyCreator自动创建代理,织入切面 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> </beans> |
执行main方法,输出:
execute before advice
execute test method
execute after advice
版权属于: 我爱我家
原文地址: http://magicwt.com/2013/09/15/aop%e7%ae%80%e4%bb%8b%e5%8f%8aspring-aop%e7%9a%844%e7%a7%8d%e5%ae%9e%e7%8e%b0/
转载时必须以链接形式注明原始出处及本声明。
深圳SEO优化公司沁阳外贸网站优化找哪家西峡网站优化公司如何优化让网站排名靠前家装行业网站优化有效果马鞍山市网站关键词优化哪家便宜优化公司网站帮助云速捷出众西安网站优化咨询商丘企业网站排名优化要多少钱花溪区网站优化营销永宁网站seo优化庐江网站首页优化多少钱网站排名优化选择金苹果钅静安区企业官网网站优化方案seo网站优化标题如何优化网站链云速捷独尊鹤壁seo网站优化注意事项河南百度网站关键词优化武汉模板网站优化整站网站优化公司有哪些百中搜网站优化网站内部优化有必要吗有实力网站推广优化软件应城网站优化推广哪家好青岛网站优化公司汕尾网站优化推广运营常熟常规网站整站优化包括什么网站初期seo优化榆次网站优化推广合肥网站快速排名优化从江县网站优化营销歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运