Spring AOP

一.什么时AOP

1.AOP是OOP(面向对象编程)的补充和完善
2.AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离
二.AOP代理

AOP代理时AOP框架创建的对象

Spring有两种代理方式

1.AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离
2.CGLIB代理,实现类的代理,而不是接口



Spring的切入点:

1.切入点是可以处发处理的连接点的集合
2.同一个切入点可触发不同的处理


Spring的切面Aspect :

1.用一个POJO 类来表示抽象的切面,
2.系统中抽象出来的的某一个系统服务功能模块

Springz的存在的五种通知:

Before:在目标方法被调用之前调用(前置通知)
AfterReturning:在某连接点正常完成后执行的通知After:当某连接点退出的时候执行的通知(最终通知)
Throws:当目标方法抛出异常时调用(异常通知)
Around:拦截对目标对象方法的调用(环绕通知

 

四.Spring中五种通知的配置文件

 

<!-- 扫描 -->
<context:component-scan base-package="cn.yunhe.biz"/>
<!-- 启用注解配置 -->
<aop:aspectj-autoproxy/>

<!--

被代理的类
<bean id="phoneBiz" class="cn.yunhe.biz.PhoneBizImpl"/>
被代理的对象
<bean id="logAspectBean" class="cn.yunhe.biz.LogAspect"/>

<aop:config>

定义一个可以被多个面共享的切入点
<aop:pointcut id="p1" expression="execution( void *Phone(int))"/>
定义切面
<aop:aspect id = "logAspect" ref="logAspectBean">
定义一个前置通知
<aop:before method="before" pointcut-ref="p1"></aop:before>
定义一个后置通知
<aop:after-returning method="afterReturning" pointcut-ref="p1"/>

最终通知
<aop:after method="after" pointcut-ref="p1"/>
环绕通知
<aop:around method="aroundTest" pointcut-ref="p1"/>
</aop:aspect>
</aop:config>&ndash;&gt;

<aop:after-throwing method="afterThrowing" pointcut-ref="p1"
throwing="e" />

 

 

案例:

1.创建一个接口和其实现类

//电话接口

public interface PhoneBiz {

void buyPhone(int num);//购买手机 void salePhone(int num) ;//销售手机
}

//手机实现类
public class PhoneBizImpl implements PhoneBiz {

int num;//库存
public void buyPhone(int num) {
System.out.println("手机进货,进货数量为:" + num + "部");}
this.num+=num;

/**public void salePhone(int num) {
System.out.println("手机销售,销售数量为:" + num + "部"); }/


public void salePhone(int num) throw OutOfStockException{

if(this.num<num){
throw new OutOfStockException("存货不足,客户需要"+num+"部手机,库存只有"+this.num+"部");
System.out.println("手机销售,销售数量为:" + num + "部");

}
}


}}

 

 

 

2.创建一个被代理的类

@Component
@Aspect
public class LogAspect {

@Pointcut("execution( void *Phone(int))")
public void p1(){}

//后置通知
@AfterReturning("p1()")
public void afterReturning(JoinPoint jp){

//得到被执行方法的参数
Object[] args = jp.getArgs();
String methodName = jp.getSignature().getName();

if ("buyPhone".equals(methodName)){

System.out.println("日志:当前时间"+currentTime()+"进货操作完毕");
}

if ("salePhone".equals(methodName)){
System.out.println("日志:当前时间"+currentTime()+"销售操作完毕");
}

}
//前置通知


@Before("p1()")
public void before(JoinPoint jp){
//得到被执行方法的参数
Object[] args = jp.getArgs();
//得到被执行的方法名
String methodName = jp.getSignature().getName();

if ("buyPhone".equals(methodName)){

System.out.println("日志:当前时间"+currentTime()+"即将进行进货操作,进货数量"+
args[0]+"部");
}

if ("salePhone".equals(methodName)){
System.out.println("日志:当前时间"+currentTime()+"即将进行销售操作,销售数量"+
args[0]+"部");
}

}
//最终通知
@After("p1()")
public void after(JoinPoint jp) throws Throwable {
String methodName = jp.getSignature().getName();
if ("buyPhone".equals(methodName)) {
System.out.println(currentTime() + "进货操作执行完毕,发生异常也要执行的最终通知...");
}
if ("salePhone".equals(methodName)) {
System.out.println(currentTime() + "销售操作执行完毕,发生异常也要执行的最终通知...");
}
}
//异常通知
@AfterThrowing(pointcut = "p1()", throwing = "e")
public void throwingException(JoinPoint jp, OutOfStackException e) {
String methodName = jp.getSignature().getName();
System.out.println(currentTime() + ":" + methodName + "方法执行的时候发生缺货异常" + e.getMessage());【

异常通知:首先自定义一个:例子:

public class OutOfStockException extends Exception{

public OutOfStockException(String msg)
}

 

}

//环绕通知
@Around("p1()")
public Object aroundTest(ProceedingJoinPoint pjp) throws Throwable {
String method = pjp.getSignature().getName();
long begin = System.currentTimeMillis();
System.out.println(currentTime()+":"+method+"方法开始执行,计时开始!");
try {
return pjp.proceed();
} finally{
long end = System.currentTimeMillis();
System.out.println(currentTime()+":"+method+"方法执行完毕,耗时"
+(end-begin)+ "毫秒");
}
}

 

public String currentTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(new Date());
}

}

 

测试: public class Demo {

ApplicationContext ac = null;

@Before
public void init(){
ac= new ClassPathXmlApplicationContext("applicationContext.xml");

}
@Test
public void test1() throws OutOfStackException {

PhoneBiz phoneBiz = ac.getBean("phoneBiz",PhoneBiz.class);
phoneBiz.buyPhone(100);
phoneBiz.salePhone(500);

System.out.println(phoneBiz.getClass().getName());

}
}

 

posted @ 2017-07-16 14:50  l小样  阅读(113)  评论(0编辑  收藏  举报