spring10-配置AOP

spring中的AOP

连接点,被拦截到的点,在spring中指的是方法 切入点,被增强的连接点 通知 在调用方法前的是前置通知,在后面的是后置通知,在catch中的是异常通知,在final中的是最终通知,整个invoke方法就是环绕通知 Target 被代理的对象 proxy 代理对象 织入 把被代理对象增强的过程 切面 通知+切入点 ### spring中的AOP要明确的事情 编写核心代码,抽取公共代码制作为通知,在配置文件中声明切入点和通知之间的关系 ## spring中AOP的配置 ### XML配置AOP aop:config 表明aop配置开始, aop:aspect 切面配置开始 id是切面的名字,ref是通知类bean aop:before 前置通知 method用于指定中的方法 pointcut是切入点

1
2
3
4
5
6
<bean id='logger' class="com.wsx.utils.logger"></bean>
<aop:config>
<aop:aspect id="logAdvice" ref="logger">
<aop:before method="pringLog" porint="execution(public void com.wsx.wsx.wsx.saveAccount())"></aop:before>
</aop:aspect>
</aop:config>
#### 通配写法 访问修饰符可以省略 如public 返回值可以是通配符,表示任意返回值 包名可以是通配符表示任意包,几个包就有几个*, 可以用..*表示当前包的所有子包 方法可以用* 参数可以用通配符,或者类型名 * *..**.*(..)
1
2
3
4
5
6
<bean id='logger' class="com.wsx.utils.logger"></bean>
<aop:config>
<aop:aspect id="logAdvice" ref="logger">
<aop:before method="pringLog" porint="execution(* *..*.*(..)"></aop:before>
</aop:aspect>
</aop:config>
#### 实际开发怎么写呢 * com.wsx.wsx.wsx.*.*(..)

各种通知都加进来

1
2
3
4
5
6
7
8
9
<bean id='logger' class="com.wsx.utils.logger"></bean>
<aop:config>
<aop:aspect id="logAdvice" ref="logger">
<aop:before method="before" porint="execution(public void com.wsx.wsx.wsx.saveAccount())"></aop:before>
<aop:after-returning method="after-returning" porint="execution(public void com.wsx.wsx.wsx.saveAccount())"></aop:after-returning>
<aop:after-throwing method="after-throwing" porint="execution(public void com.wsx.wsx.wsx.saveAccount())"></aop:after-throwing>
<aop:after method="after" porint="execution(public void com.wsx.wsx.wsx.saveAccount())"></aop:after>
</aop:aspect>
</aop:config>

配置切点

减少代码量,写在aop:aspect外可以所有切面都可以使用(写在aspect之前),写在aop:aspect内只在内部有用

1
2
3
4
5
6
7
8
9
10
<bean id='logger' class="com.wsx.utils.logger"></bean>
<aop:config>
<aop:aspect id="logAdvice" ref="logger">
<aop:before method="before" pointcut-ref="pt1"></aop:before>
<aop:after-returning method="after-returning" pointcut-ref="pt1"></aop:after-returning>
<aop:after-throwing method="after-throwing" pointcut-ref="pt1"></aop:after-throwin>
<aop:after method="after" pointcut-ref="pt1"></aop:after>
<aop:pointcut id="pt1" expression="execution(public void com.wsx.wsx.wsx.saveAccount())"></aop:pointcut>
</aop:aspect>
</aop:config>

配置环绕通知

当我们配置了环绕通知以后,spring就不自动帮我们调用被代理对象了

1
<aop:around method="?" pointcut-ref="pt1"></aop:around>
1
2
3
4
5
6
7
8
9
10
public Object arroundPringLog(ProceedingJoinPoint pjp){
Object rtValue = null;
try{
Object[] args = pjp.getArgs(); // 获得参数
rtValue = pip.proceed(args); //调用函数
return rtValue;
}catch(Throwable t){
}finally{
}
}
### 注解配置AOP #### 开启注解
1
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
#### @Aspect 表明当前类是一个切面类 #### @Pointcut 切入点表达式
1
2
@pointcut("execution(public void com.wsx.wsx.wsx.saveAccount())")
private void pt1(){}
#### @Before 表明当前方法是一个前置通知, AfterReturning、AfterThrowing、After、Arount同理
1
2
@Before("pt1()")
public void f(){}
#### 注解调用顺序的问题 前置、最终、后置/异常

纯注解

加在类的前面即可

1
2
3
@Configuration
@ComponentScan(..)
@EnableAspectJAutoProxy