10【掌握】普通AOP开发(XML方式)
1,AOP开发中的概念
1,JoinPoint(连接点):所谓连接点是指那些被拦截的点,而spring中这些点就是指方法,因为spring只支持方法类型的连接点。 —指目标类里面的方法
2,PointCut(切入点):所谓切入点就是指我们要对那些JoinPoint进行拦截的定义。
如com.sxt.domain.Man.*(…)
3,Advice(通知/增强):所谓通知/增强,就是指拦截到JoinPoint后需要完成的事情。他分为前置通知/增强,后置通知/增强,异常通知/增强,最终通知/增强,环绕
通知/增强(切面要完成的功能);
4,Introduction(引介):引介是一种特殊的Advice,在不修改代码的前提下,引介可以在运行期为类动态的添加一些方法或Field。
5,Target(目标):代理对象的目标对象(要增强的类)
6,Weaving(织入):把Advice应用到Target的过程
7,Proxy(代理):一个类被AOP注入增强后,就产生了一个结果代理类
8,Aspect(切面):是PointCut和Advice(Introduction)的结合
9,画图
2,开发和配置步骤
创建项目并导包
创建目标类
创建前置通知
配置applicationContext.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: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
">
<!-- 在spring的面向切面 的目标对象只能是通过spring的IOC容器创建的对象 -->
<!-- 声明目标对象 -->
<bean id="man" class="com.sxt.domain.Man"></bean>
<bean id="stu" class="com.sxt.domain.Student"></bean>
<!-- 声明增加类 [通知 前置通知 后置通知 异常通知 最终通知 环绕通知] -->
<bean id="myBeforeAdvise" class="com.sxt.advise.MyBeforeAdvise"></bean>
<bean id="myAfterAdvise" class="com.sxt.advise.MyAfterAdvise"></bean>
<!-- 配置aop -->
<aop:config>
<!-- 声明一个切入点
expression:表达式
-->
<aop:pointcut expression="execution(* com.sxt.domain.*.*(..))" id="pc"/>
<!-- <aop:pointcut expression="execution(* com.sxt.service.impl.*.*(..))"
id="pc"/> -->
<!-- 织入 -->
<aop:advisor advice-ref="myBeforeAdvise" pointcut-ref="pc"/>
<aop:advisor advice-ref="myAfterAdvise" pointcut-ref="pc"/>
</aop:config>
</beans>
3,后置增强
创建MyAfterAdvise
配置applicaitonContext.xml
4,环绕增强
创建MyAroundAdvise
/**
* 增强的通知类
* @author LJH
*
*/
public class MyAroundAdvise implements MethodInterceptor{
/**
* 前置增强
*/
public void before(){
System.out.println("前置加强");
}
/**
* 后置增强
*/
public void after(){
System.out.println("后置加强");
}
/**
* invocation 执行对象
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
before();
//执行目标对象的方法
Object object = invocation.proceed();
after();
return object;
}
}
配置applicaitonContext.xml
5,异常增加
创建MyExceptionAdvise
配置applicaitonContext.xml
修改Studnet.java测试
11-【掌握】使用AspectJ AOP开发(XML方式)
创建目类
创建增强类
/**
* 通知类
*
* @author LJH
*
*/
public class MyAdvise {
/**
* 前置增强
*/
public void before() {
System.out.println("前置加强");
}
/**
* 后置增强
*/
public void after() {
System.out.println("后置加强");
}
/**
* 环绕增强的方法
*/
public void around(ProceedingJoinPoint point){
before();
try {
point.proceed();
} catch (Throwable e) {
e.printStackTrace();
}//执行目标方法
after();
}
/**
* 异常增强
* tw 和要织入里面的<aop:after-throwing method="error" pointcut-ref="pc"
* throwing="tw"/>
* throwing的值一样
*/
public void error(Throwable tw){
System.out.println("产生异常:"+tw.getMessage());
}
}
配置applicationContext.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: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
">
<!-- 在spring的面向切面 的目标对象只能是通过spring的IOC容器创建的对象 -->
<!-- 声明目标对象 -->
<bean id="man" class="com.sxt.domain.Man"></bean>
<!-- 声明增加类 [通知 前置通知 后置通知 异常通知 最终通知 环绕通知] -->
<bean id="myAdvise" class="com.sxt.advise.MyAdvise"></bean>
<!-- 配置aop -->
<aop:config>
<aop:aspect ref="myAdvise">
<!-- 声明切面 -->
<aop:pointcut expression="execution(* com.sxt.domain.*.*(..))"
id="pc"/>
<!-- 织入 -->
<!-- <aop:before method="before" pointcut-ref="pc"/>
<aop:after-returning method="after" pointcut-ref="pc"/> -->
<!-- <aop:around method="around" pointcut-ref="pc"/> -->
<!-- throwing=tw tw要和通知类里面的error方法的参数名一致 -->
<aop:after-throwing method="error" pointcut-ref="pc" throwing="tw"/>
</aop:aspect>
</aop:config>
</beans>
12-【熟悉】AOP开发(注解方式)
创建目标类
创建MyAdvise
/**
* 通知类
*
* @author LJH
*
*/
@Component
@Aspect //这个类是一个切面类
public class MyAdvise {
/**
* 定义切面 和xml配置里面的一个意思 <aop:pointcut expression="execution(*
* com.sxt.domain.*.*(..))" id="pc"/>
*/
@Pointcut("execution(* com.sxt.domain.*.*(..))")
public void pc(){
}
/**
* 前置增强
*/
//@Before("execution(* com.sxt.domain.*.*(..))")
@Before("pc()")
public void before() {
System.out.println("前置加强");
}
/**
* 后置增强
*/
//@AfterReturning("execution(* com.sxt.domain.*.*(..))")
@AfterReturning("pc()")
public void after() {
System.out.println("后置加强");
}
/**
* 环绕增强的方法
*/
//@Around("execution(* com.sxt.domain.*.*(..))")
@Around(value="pc()")
public void around(ProceedingJoinPoint point){
before();
try {
point.proceed();
} catch (Throwable e) {
e.printStackTrace();
}//执行目标方法
after();
}
/**
* 异常增强
* tw 和要织入里面的<aop:after-throwing method="error" pointcut-ref="pc"
* throwing="tw"/>
* throwing的值一样
*/
//@AfterThrowing(value="execution(* com.sxt.domain.*.*(..))",throwing="tw")
@AfterThrowing(value="pc()",throwing="tw")
public void error(Throwable tw){
System.out.println("产生异常:"+tw.getMessage());
}
}
配置applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context
/spring-context.xsd
">
<!-- 扫描 -->
<context:component-scan base-package="com.sxt.domain">
</context:component-scan>
<!-- 扫描切面类 -->
<context:component-scan base-package="com.sxt.advise">
</context:component-scan>
<!-- 开启注解的切面配置 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
测试
记录方法的性能的AOP
/**
* 性能通知类
*
* @author LJH
*
*/
@Component
@Aspect //这个类是一个切面类
public class LogAdvise {
/**
* 定义切面 和xml配置里面的一个意思 <aop:pointcut expression="execution(*
* com.sxt.domain.*.*(..))" id="pc"/>
*/
@Pointcut("execution(* com.sxt.domain.*.*(..))")
public void pc(){
}
private ThreadLocal<Long> time=new ThreadLocal<>();
/**
* 前置增强
*/
//@Before("execution(* com.sxt.domain.*.*(..))")
@Before("pc()")
public void before() {
Long start=System.currentTimeMillis();
time.set(start);
}
/**
* 后置增强
*/
//@AfterReturning("execution(* com.sxt.domain.*.*(..))")
@AfterReturning("pc()")
public void after() {
Long end=System.currentTimeMillis();
Long start=time.get();
System.out.println("耗时:"+(end-start));
}
/**
* 环绕增强的方法
*/
//@Around("execution(* com.sxt.domain.*.*(..))")
@Around(value="pc()")
public void around(ProceedingJoinPoint point){
Long start=System.currentTimeMillis();
try {
point.proceed();
} catch (Throwable e) {
e.printStackTrace();
}//执行目标方法
Long end=System.currentTimeMillis();
System.out.println("耗时:"+(end-start));
}
}