AOP面向切面,通过预编译和运行期动态代理实现程序功能的统一维护
AOP可以使业务各个部分隔离,使业务耦合降低,提升重用性和开发效率
面向接口编程
public interface StudentService {
public void addStudent(String name);
}
实现类
public class StudentServiceImpl implements StudentService{
@Override
public void addStudent(String name) {
// System.out.println("开始添加学生"+name);
System.out.println("添加学生"+name);
// System.out.println("完成学生"+name+"的添加");
}
}
<?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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="studentService" class="com.java.service.impl.StudentServiceImpl"></bean>
</beans>
接口多态
父类的引用直接指向具体的实现
接口调用add方法
public class T {
private ApplicationContext ac;
@Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
}
@Test
public void test1() {
StudentService studentService=(StudentService)ac.getBean("studentService");
studentService.addStudent("张三");
}
}
日志记录
前置通知,后置通知,环绕通知,返回通知,异常通知
前置通知执行方法前执行操作
public class StudentServiceAspect {
public void doBefore(JoinPoint jp){
System.out.println("类名:"+jp.getTarget().getClass().getName());
System.out.println("方法名:"+jp.getSignature().getName());
System.out.println("开始添加学生:"+jp.getArgs()[0]);
}
}
aop:aspect 定义切面类
aop:pointcut spring的切点定义到方法 (返回值 包路径 *.*(类和方法名) 方法的参数)
<?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">
<bean id="studentServiceAspect" class="com.java.advice.StudentServiceAspect"></bean>
<aop:config>
<aop:aspect id="studentServiceAspect" ref="studentServiceAspect">
<aop:pointcut expression="execution(* com.java.service.*.*(..))" id="businessService"/>
<aop:before method="doBefore" pointcut-ref="businessService"/>
<aop:after method="doAfter" pointcut-ref="businessService"/>
<aop:around method="doAround" pointcut-ref="businessService"/>
<aop:after-returning method="doAfterReturning" pointcut-ref="businessService"/>
<aop:after-throwing method="doAfterThrowing" pointcut-ref="businessService" throwing="ex"/>
</aop:aspect>
</aop:config>
</beans>
上面的配置已经把service都扫描进去,在执行addService的时候通过配置aop;before 通过代理先执行doBefore方法
public class StudentServiceImpl implements StudentService{
@Override
public void addStudent(String name) {
System.out.println("添加学生"+name);
System.out.println(1/0);
}
}
切面类的其他通知
环绕通知doAround有返回值为addStudent方法的返回值,当要执行方法时候先执行proceed调用代理执行业务的方法
返回通知 方法要返回return之前的通知,方法还没有执行完
异常通知 Throwable 异常解析
public void doAfter(JoinPoint jp){
System.out.println("类名:"+jp.getTarget().getClass().getName());
System.out.println("方法名:"+jp.getSignature().getName());
System.out.println("学生添加完成:"+jp.getArgs()[0]);
}
public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("添加学生前");
Object retVal=pjp.proceed();
System.out.println(retVal);
System.out.println("添加学生后");
return retVal;
}
public void doAfterReturning(JoinPoint jp){
System.out.println("返回通知");
}
public void doAfterThrowing(JoinPoint jp,Throwable ex){
System.out.println("异常通知");
System.out.println("异常信息:"+ex.getMessage());
}