AOP
- 关注横切
- 提取散布在各个封装里的重复功能,重新组织
- 让业务层更加关心核心逻辑
- 解耦
- SEE Aspect Oriented Programming-Wikipedia:
Spring框架里的AOP
- 两种主要的实现方式
- 在XML中配置
- 使用Annotation进行配置
Sample
- 本样例考虑Logging,日志记录
- 模拟网站的登陆行为,省略内部实现。
- User:用户,方法login():登陆
- LogService: 日志服务
在XML中配置
- 切面类直接编写,切入点以及行为方法在XML中定义
注意!
- 配置XML文件时,在文件头加入相应的XMLNS以及schemaLocation
- 在这里,aop对应的是在xmlns中增加xmlns:aop=”http://www.springframework.org/schema/aop”
以及shecma中增加http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd” - 搭建环境时,下载spring以及aspectJ的jar包作为ExternalJAR导入
- AspectJ官网上下的JAR记得解压后导入,不能直接使用
- User
@Component
public class User {
public void login(){
System.out.println("User:: user logged in");
}
public void logout(){
System.out.println("User:: user logged out");
}
}
- LogService
@Component
public class LogService {
public void logBefore()
{
System.out.println("A user is to log in");
}
public void logAfter(){
System.out.println("A user already logged in");
}
}
- XML配置文件
<?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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!--
<aop:aspectj-autoproxy /> equals to <bean
class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"
/>
-->
<context:component-scan base-package="indi.zhihan.test.aop.xml"/>
<aop:config>
<aop:aspect id="logEvent" ref="logService">
<aop:pointcut id="userLogin"
expression="execution(* indi.zhihan.test.aop.xml.User.login(..))"
/>
<aop:before pointcut-ref="userLogin" method="logBefore"/>
<aop:after-returning pointcut-ref="userLogin" method="logAfter"/>
</aop:aspect>
</aop:config>
<!-- <aop:aspectj-autoproxy /> -->
</beans>
- 重点
<aop:config>
<aop:aspect id="logEvent" ref="logService">
<aop:pointcut id="userLogin"
expression="execution(* indi.zhihan.test.aop.xml.User.login(..))"
/>
<aop:before pointcut-ref="userLogin" method="logBefore"/>
<aop:after-returning pointcut-ref="userLogin" method="logAfter"/>
</aop:aspect>
</aop:config>
- 在spring的xml中声明用于横切的类(LogService)了joinpoint以及before和after方法
使用Annotation配置
- User相同
- LogService
@Component
@Aspect
public class LogService {
@Pointcut("execution(* indi.zhihan.test.aoc.annotation.Monkey.login(..))")
public void userLogin(){
}
@Before(value="userLogin()")
public void logBefore()
{
System.out.println("A user is to log in");
}
@AfterReturning(value="userLogin()")
public void logAfter(){
System.out.println("A user already logged in");
}
}
- XML配置
<?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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!--
<aop:aspectj-autoproxy /> equals to <bean
class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"
/>
-->
<context:component-scan base-package="indi.zhihan.test.aop.annotation"/>
<aop:aspectj-autoproxy />
</beans>
- 重点:
- xml中加入
- 使用aspectJ的annotation在类中直接对aspcet以及其中的
joinpoint、before、after、around方法进行描述
参考资料
Aspect Oriented Programming-Wikipedia:
Spring AOP AspectJ - 丁应思 - 博客园
错误提示:The prefix _aop_ for element _aop_config_ is not bound. - Shang的专栏 - 博客频道 - CSDN.NET