1.什么是AOP:面向切面的编程.
我的理解就是一些功能已经完成了但是新增要求新增一些功能,AOP就是用来在不影响源代码的前提下,动态的附加功能。
2.现在有已经完成的几个方法,要求在方法执行之前和结束之后输出日志信息
1.已有的接口和类
package aop.day2;
public interface IUserService {
void saveUser();
void deleteById(Long id);
Integer update();
}
package aop.day2;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements IUserService{
@Override
public void saveUser() {
System.out.println("saveUser成功!");
}
@Override
public void deleteById(Long id) {
System.out.println("delete成功!");
}
@Override
public Integer update() {
System.out.println("update成功!");
double r = Math.random();
System.out.println("random: "+r);
if(r<0.8) {
throw new RuntimeException("update error...");
}
return (int)(r*100);
}
}
2.创建日志输出的类
package aop.day2;
import org.aspectj.lang.JoinPoint;
public class LogAspect {
//JoinPoint可获取到当前执行方法的一些信息
public void before(JoinPoint jp) {
System.out.println("log before-----------"+jp.getSignature().getName());
}
public void after(JoinPoint jp) {
System.out.println("log after-----------"+jp.getSignature().getName());
}
public void afterReturn(JoinPoint jp,Object returnObj) {
System.out.println("log afterReturn-----------"+jp.getSignature().getName()+"返回结果是:"+returnObj);
}
public void afterThrow(JoinPoint jp,Throwable ex) {
System.out.println("log afterThrow-----------"+jp.getSignature().getName()+"异常信息是:"+ex);
System.out.println();
}
}
3.创建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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="target" class="aop.day2.UserServiceImpl"></bean>
<bean id="logAspect" class="aop.day2.LogAspect"></bean>
<aop:config>
<aop:aspect ref="logAspect">
<!-- 不想重复写pointcut,如果"(*)"只会执行一次,如果是"(..)"会在每一个方法执行的时候都执行一次-->
<aop:pointcut expression="execution(* aop.day2.IUserService.*(..))" id="pt"/>
<aop:before method="before" pointcut="execution(* aop.day2.IUserService.*(..))"/>
<!-- 无论代码是否发生异常都会执行 -->
<aop:after method="after" pointcut="execution(* aop.day2.IUserService.*(..))"/>
<!-- 只有代码正确返回,没有抛出异常才会执行
returning:代表将来的连接点方法执行完后,返回的返回结果需要赋值给returning属性对应的方法参数
-->
<aop:after-returning method="afterReturn" pointcut-ref="pt" returning="returnObj"/>
<!-- 当目标方法抛出异常时执行 -->
<aop:after-throwing method="afterThrow" pointcut-ref="pt" throwing="ex"/>
</aop:aspect>
</aop:config>
</beans>
4.测试类
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import aop.day2.IUserService;
public class Aop_day2 {
@Test
public void test_aop_schema() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("aop/day2/aop.xml");
IUserService service = ac.getBean("target",IUserService.class);
service.deleteById(1L);
service.saveUser();
service.update();
}
}