aop联盟 定义 aop通知类型,spring 对 aop联盟规范支持。
aop联盟定义5种通知
前置通知 org.springframework.aop.MethodBeforeAdvice
在目标方法执行前实施增强
后置通知 org.springframework.aop.AfterReturningAdvice
在目标方法执行后实施增强
环绕通知 org.aopalliance.intercept.MethodInterceptor
在目标方法执行前后实施增强
异常抛出通知 org.springframework.aop.ThrowsAdvice
在方法抛出异常后实施增强
引介通知 org.springframework.aop.IntroductionInterceptor(了解)对一个类进行增强(添加方法或属性等)
在目标类中添加一些新的方法和属性
如果使用aop联盟规范进行aop开发,所有的通知必须实现接口。(底层为了确定通知方法名称)
需要总结:
需要根据AOP联盟确定一个通知类型:这里使用环绕通知(环绕通知需要手动开启方法)
所以切面类随便写,随便实现一个通知类型,重写里面的invok方法在,通过参数调用
proceed()执行目标类,前后可以写代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package
com.mickeymouse.proxy;
import
org.aopalliance.intercept.MethodInterceptor;
import
org.aopalliance.intercept.MethodInvocation;
/**
* 切面类:包含两个通知(增强)
环绕通知必须手动执行方法
* @author Mickey-Mouse
*
*/
public
class
MyAspect
implements
MethodInterceptor {
public
Object invoke(MethodInvocation mi)
throws
Throwable {
System.out.println(
"已校验是否符合身份"
);
//环绕通知必须手动执行方法
Object object = mi.proceed();
System.out.println(
"方法已经执行完--->后处理"
);
return
object;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package
com.mickeymouse.proxy;
public
class
ProductsServiceImpl
implements
ProductsService {
/**
* 目标类:
* 里面有两个连接点
*/
public
void
addProducts(){
System.out.println(
"添加商品成功"
);
}
public
void
updateProducts(){
System.out.println(
"修改商品成功"
);
}
}
|
与AOP的自动代理的区别在于:
半自动代理没有使用AOP约束,要手动配置代理类与目标类的关系
半自动代理是基于ProxyFactoryBean的代理类:
缺点:
* 配置麻烦:
* 需要为每一个要增强的类配置一个ProxyFactoryBean.(只要有增强,就需要写一个ProxyFactoryBean的配置)
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
|
<?
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.xsd">
<!-- bean definitions here -->
<!-- 半自动代理模式 -->
<!-- 生成切面类 -->
<
bean
id
=
"myAspect"
class
=
"com.mickeymouse.proxy.MyAspect"
/>
<!-- 生成目标类 -->
<
bean
id
=
"productsService"
class
=
"com.mickeymouse.proxy.ProductsServiceImpl"
/>
<!-- 让Spring来创建代理工厂对象 -->
<
bean
id
=
"proxyFactoryBean"
class
=
"org.springframework.aop.framework.ProxyFactoryBean"
>
<!-- 设置目标类 -->
<
property
name
=
"target"
ref
=
"productsService"
></
property
>
<!-- 设置切面类"名字" -->
<
property
name
=
"interceptorNames"
value
=
"myAspect"
></
property
>
<!-- 设置切面类需要连接的接口(optimize与接口二选一即可,Spring可以自动识别,接口就动态代理,没有就CGLIB) -->
<
property
name
=
"proxyInterfaces"
value
=
"com.mickeymouse.proxy.ProductsService"
></
property
>
<!-- 是否强制使用使用CGLIB -->
<
property
name
=
"optimize"
value
=
"true"
></
property
>
</
bean
>
</
beans
>
|
测试类:
1
2
3
4
5
6
7
|
@Test
public
void
test1(){
ApplicationContext applicationContext =
new
ClassPathXmlApplicationContext(
"applicationContext.xml"
);
ProductsService bean = applicationContext.getBean(
"proxyFactoryBean"
,ProductsService.
class
);
bean.addProducts();
bean.updateProducts();
}
|
结果:
AOP的半自动代理:(配置带有切入点的切面---->个别方法)(了解)
配置文件:(其他部分是一样的 , 同上)
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
36
37
38
39
|
<?
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.xsd">
<!-- Spring帶有切入点的切面=============== -->
<!-- 配置目标类 -->
<
bean
id
=
"customerDao"
class
=
"com.itheima.spring.demo4.CustomerDao"
/>
<!-- 配置通知:(环绕通知) -->
<
bean
id
=
"myAroundAdvice"
class
=
"com.itheima.spring.demo4.MyAroundAdvice"
/>
<!-- 配置带有切入点的切面 -->
<
bean
id
=
"myAdvisor"
class
=
"org.springframework.aop.support.RegexpMethodPointcutAdvisor"
>
<!-- 表达式: 正则表达式 : .:任意字符 *:任意次数-->
<!-- 拦截所有方法 -->
<!-- <property name="pattern" value=".*"/> -->
<!-- 只拦截update方法 -->
<!-- <property name="pattern" value="com\.itheima\.spring\.demo4\.CustomerDao\.update"/> -->
<!-- 拦截update和delete方法 -->
<!-- <property name="patterns" value="com\.itheima\.spring\.demo4\.CustomerDao\.update,com\.itheima\.spring\.demo4\.Cus tomerDao\.delete"/> -->
<!-- 拦截所有以save和update结束名的方法 -->
<
property
name
=
"patterns"
value
=
".*save.*,.*update.*"
/>
<!-- 配置增强 -->
<
property
name
=
"advice"
ref
=
"myAroundAdvice"
/>
</
bean
>
<!-- 配置生成代理 -->
<
bean
id
=
"proxyFactoryBean"
class
=
"org.springframework.aop.framework.ProxyFactoryBean"
>
<!-- 配置目标 -->
<
property
name
=
"target"
ref
=
"customerDao"
/>
<!-- 配置代理目标类 -->
<
property
name
=
"proxyTargetClass"
value
=
"true"
/>
<!-- 配置拦截的名称 -->
<
property
name
=
"interceptorNames"
value
=
"myAdvisor"
/>
</
bean
>
</
beans
>
|