您的位置:首页 > 编程语言 > ASP

AOP的自动代理(基于AspectJ框架)

2015-10-20 00:00 591 查看

AOP的通知类型:

aop联盟定义aop通知类型,spring对aop联盟规范支持。

AOP联盟不是Spring的,先是AOP联盟定义了一个接口org.springframework.aop.Advice而Spring觉得不错,就改写了分成5种类型

aop联盟定义5种通知

前置通知org.springframework.aop.MethodBeforeAdvice

在目标方法执行前实施增强

后置通知org.springframework.aop.AfterReturningAdvice

在目标方法执行后实施增强

环绕通知org.aopalliance.intercept.MethodInterceptor

在目标方法执行前后实施增强

异常抛出通知org.springframework.aop.ThrowsAdvice

在方法抛出异常后实施增强

引介通知org.springframework.aop.IntroductionInterceptor(了解)对一个类进行增强(添加方法或属性等)

在目标类中添加一些新的方法和属性

如果使用aop联盟规范进行aop开发,所有的通知必须实现接口。(底层为了确定通知方法名称)

Advisor和Aspect区别:

Advisor:Spring传统的切面.一般都是由一个切入点和一个通知的组合.(单个)

Aspect:Aspect是真正意义上的切面.是由多个切入点和多个通知组合.(多个)

AOP基于AspectJ的自动代理(实现了接口,配置用<aop:Advisor>):

因为使用AOP,所以Spring需要的包以外,还要导入

联盟API开发包.jar----------->(依赖包下)

AOP所需要的核心包.jar----->(主包下)



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的DTD约束

与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

26

27

28

29

30

31

32
<?
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"
/>

<!--利用AOP约束,建立切面的通知与切入点之间的关系-->

<!--AOP的配置头-->

<
aop:config
>


<!--


切入点配置:


expression:AspectJ编程的表达式(说明利用了这个框架,所以注意导包)


Id:切入点名称,连接通知的索引名


-->


<
aop:pointcut
expression
=
"execution(*com.mickeymouse.proxy.ProductsServiceImpl.*())"
id
=
"mypointcut"
/>


<!--


切面配置:


advice-ref:通知/增强点


pointcut-ref=切点


proxy-target-class="true"表示强制使用CGLIB


因为Spring默认是使用动态代理的方式,而CGLIB是使用目标类生成子类代理的方式(也就是不使用接口)


-->


<
aop:advisor
advice-ref
=
"myAspect"
pointcut-ref
=
"mypointcut"
/>

</
aop:config
>

</
beans
>
XML分析:(总结4步)
1.配置切面类的Bean实例

2.配置目标类的Bean实例

3.配置切入点(结合exeution表达式)

4.配置切面(切入点和通知/加强点)



结果:



AOP自动代理:(切面类不需要实现接口/配置用<aop:aspect>)

1.目标类:(同上)

2.切面类:(随便写)eg
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21
package
com.mickeymouse.proxy.auto;

import
org.aspectj.lang.ProceedingJoinPoint;

/**


*切面类:随便写


*@authorMickey-Mouse


*


*/

public
class
MyAspect{


/**


*环绕配置切面类


*@paramproceedingJoinPoint环绕需要手动开启方法


*@return


*@throwsThrowable


*/


public
Objectaround(ProceedingJoinPointproceedingJoinPoint)
throws
Throwable{


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


Objectobject=proceedingJoinPoint.proceed();


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


return
object;


}

}
3.XML配置:
1

2

3

4

5

6

7

8

9

10

11

12

13

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


<!--切面类-->


<
bean
id
=
"myAspect"
class
=
"com.mickeymouse.proxy.auto.MyAspect"
/>


<!--目标类-->


<
bean
id
=
"productsService"
class
=
"com.mickeymouse.proxy.auto.ProductsServiceImpl"
/>


<!--AOP自动代理配置:-->


<
aop:config
>


<!--切入点-->


<
aop:pointcut
expression
=
"execution(*com.mickeymouse.proxy.auto.ProductsServiceImpl.*())"
id
=
"mypointcut"
/>


<!--切面-->


<
aop:aspect
ref
=
"myAspect"
>


<
aop:around
method
=
"around"
pointcut-ref
=
"mypointcut"
/>


</
aop:aspect
>


</
aop:config
>
测试类:
1

2

3

4

5

6

7

8

9

10

11

12

13
package
com.mickeymouse.proxy.auto;

import
org.junit.Test;

import
org.springframework.context.ApplicationContext;

import
org.springframework.context.support.ClassPathXmlApplicationContext;

public
class
TestDemo{


@Test


public
void
test1(){


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


ProductsServicebean=applicationContext.getBean(
"productsService"
,ProductsService.
class
);


bean.addProducts();


bean.updateProducts();


}

}
结果图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: