了解AOP
我是一个新手,可能表述的不是特别清楚,如果有误,希望可以指点出来。
spring AOP是继spring IOC之后的srping框架的又一大特性,它也是spring框架的核心内容。
AOP是一种思想,所有符合AOP思想的技术,都可以看作AOP的实现,spring框架已经基本吧AOP的思想实现了。在众多的AOP实现技术中,spring AOP做的最好,也很成熟。
spring AOP的实现是基于java的代理机制。
springAOP的基本组成部分。
AOP的简单实现:
一个普通的类-》有特定功能的类a.继承类 b.实现接口 c.注解 d.配置
1.模拟三层dao层的实现
package org.awen.dao;
public class studentDao {
public void addStudent(int id) {
System.out.println("增加学生");
}
public void deleteStudent(int id) {
System.out.println("删除学生");
}
}
2.配置applicationContext.xml
3.实现LogBefore,实现一个接口
package org.awen.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class LogBefore implements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
// TODO 自动生成的方法存根
System.out.println("前置通知");
}
}
4.实现test类,测试类。
package org.awen.test;
import org.awen.dao.studentDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void testAOP() {
ApplicationContext contet=new ClassPathXmlApplicationContext("applicationContext.xml");
//执行从springIOC容器中获取一个id为student的对象
studentDao studentdao=(studentDao)contet.getBean("studentDao");
//从ioc中拿方法
studentdao.addStudent(1);
studentdao.deleteStudent(1);
/*
String[] ids=contet.getBeanDefinitionNames();
for(String id:ids) {
System.out.println(id);
}
*/
}
public static void main(String[] args) {
testAOP();
}
}
如果同时为两个方法,添加前置通知的话(addStudent和deleteStudent)那么就需要改变applicationContext.xml
1.模拟三层dao层的实现
2.配置applicationContext.xml
3.实现LogAfter,实现一个接口
package org.awen.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class LogAfter implements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
// TODO 自动生成的方法存根
System.out.println("后置通知");
}
}
4.实现test类,测试类。
1.模拟三层dao层的实现
2.配置applicationContext.xml
3.实现afterThrowind,实现一个接口
package org.awen.aop;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class LogException implements ThrowsAdvice{
//异常通知得具体方法
public void afterThrowind(Method method, Object[] args, Object target , Throwable ax){
System.out.println("异常");
//System.out.println("异常通知:目标对象"+target+",方法名"+method.getName()+",方法的参数个数:"+args.length+",异常类型:"+ax.getMessage());
}
}
4.实现test类,测试类。
1.模拟三层dao层的实现
2.配置applicationContext.xml
3.实现LogBefore,实现一个接口
public class LogAround implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
// TODO 自动生成的方法存根
Object result=null;
//方法体1...
try {
//方法体2..
System.out.println("用环绕通知实现的【前置通知】");
result=invocation.proceed();//在此方法之前的都是前置通知,之后的都是后置通知
System.out.println("用环绕通知实现的【后置通知】");
System.out.println("异常通知:目标对象"+invocation.getThis()+",方法名"+invocation.getMethod()+",方法的参数个数:"+invocation.getArguments().length);
}catch(Exception e) {
//方法体3...
System.out.println("用环绕通知实现的【异常通知】");
}
return result;
}
}
4.实现test类,测试类。
实例,LogSchmema
package org.awen.aopSchemema;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class LogSchmema {
public void before() {
// TODO 自动生成的方法存根
System.out.println("用schmema实现的前置通知");
}
public void afterReturning(JoinPoint jp,Object objectvalue) {
System.out.println("用schmema实现的后置通知"+jp.getThis()+objectvalue);
}
public void whenException(JoinPoint jp) {
System.out.println("用schmema实现的异常通知");
}
public Object around(ProceedingJoinPoint pj) throws Throwable {
System.out.println("用schmema实现的环绕前置通知");
Object result=null;
try {
result=pj.proceed();
System.out.println("用schmema实现的环绕后置通知");
}catch(Exception e) {
System.out.println("用schemema实现的环绕异常通知");
}
return result;
}
}
applicationContext.xml配置:
1.配置aoolicationContext.xml文件:
2.编写LogAnnotation.java这个类:
@Component("logAnnotation")//将LogBeforeAnnotation纳入springIOC容器中
@Aspect//此类事一个通知类 这个并不需要扫描器
public class LogAnnotation{
//前置通知
@Before("execution(public void org.awen.dao.studentDao.addStudent(int))")
public void myBefore(JoinPoint jp) {
System.out.println("异常通知:目标对象"+jp.getTarget()+",方法名"+jp.getSignature().getName()+",方法的参数个数:"+Arrays.toString(jp.getArgs()));
System.out.println("<注解形式-前置通知>");
}
//后置通知
@AfterReturning("execution(public void org.awen.dao.studentDao.addStudent(int))")
public void myAfter() {
System.out.println("<注解形式-后置通知>");
}
//环绕通知
@Around("execution(public void org.awen.dao.studentDao.addStudent(int))")
public void myAround(ProceedingJoinPoint jp) throws Throwable {
System.out.println("<注解形式-环绕通知-前置通知>");
//方法之前:前置通知
try {
//方法的执行体
jp.proceed();
}catch(Exception e) {
//发生异常执行的通知
System.out.println("<注解形式-环绕通知-后置通知>");
}finally {
//最终通知
System.out.println("环绕的最终通知");
}
}
//异常通知:如果只捕获特定类型的已存在异常
@AfterThrowing(pointcut="execution(public void org.awen.dao.studentDao.addStudent(int))",throwing="e")
public void myException(JoinPoint jp,NullPointerException e) {
System.out.println("<注解形式-异常通知>"+e.getMessage());
}
//最终通知
@After("execution(public void org.awen.dao.studentDao.addStudent(int))")
public void myAfter1() {
System.out.println("<注解形式-最终i形式----通知>");
}
/**/