springAOP面向切面编程

了解AOP
我是一个新手,可能表述的不是特别清楚,如果有误,希望可以指点出来。
spring AOP是继spring IOC之后的srping框架的又一大特性,它也是spring框架的核心内容。
AOP是一种思想,所有符合AOP思想的技术,都可以看作AOP的实现,spring框架已经基本吧AOP的思想实现了。在众多的AOP实现技术中,spring AOP做的最好,也很成熟。
spring AOP的实现是基于java的代理机制。
springAOP的基本组成部分。springAOP面向切面编程_第1张图片
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类,测试类。

以上都是用实现接口的方法来进行的。



下面都是使用Schema的方法来进行的。

实例,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形式----通知>");
	}
	/**/

你可能感兴趣的:(学习,spring)