您的位置:首页 > 运维架构

AOP的半自动代理 及 缺点

2015-10-20 00:00 295 查看

AOP的通知类型:

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的半自动代理(不带有切入点的切面---所有方法)

1.切面类
需要总结:

需要根据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;

/**


*切面类:包含两个通知(增强)


环绕通知必须手动执行方法


*@authorMickey-Mouse


*


*/

public
class
MyAspect
implements
MethodInterceptor{


public
Objectinvoke(MethodInvocationmi)
throws
Throwable{


System.out.println(
"已校验是否符合身份"
);


//环绕通知必须手动执行方法


Objectobject=mi.proceed();


System.out.println(
"方法已经执行完--->后处理"
);


return
object;


}

}
2.目标类(已实现接口)
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(
"修改商品成功"
);


}

}
3.半自动代理XML配置
与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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">

<!--beandefinitionshere-->


<!--半自动代理模式-->


<!--生成切面类-->


<
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(){


ApplicationContextapplicationContext=
new
ClassPathXmlApplicationContext(
"applicationContext.xml"
);


ProductsServicebean=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/beanshttp://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"
>


<!--表达式:正则表达式:.:任意字符*:任意次数-->

<!--拦截所有方法-->

<!--<propertyname="pattern"value=".*"/>-->

<!--只拦截update方法-->

<!--<propertyname="pattern"value="com\.itheima\.spring\.demo4\.CustomerDao\.update"/>-->

<!--拦截update和delete方法-->

<!--<propertyname="patterns"value="com\.itheima\.spring\.demo4\.CustomerDao\.update,com\.itheima\.spring\.demo4\.CustomerDao\.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
>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: