现在的位置: 首页 > 综合 > 正文

Spring学习笔记(AOP面向切面编程)

2013年10月05日 ⁄ 综合 ⁄ 共 5191字 ⁄ 字号 评论关闭

 AOP是“Aspect  Oriented Programming”的缩写,意思是面向切面编程。面向切面的编程是一种新的编程技术,追求的是调用者和被调用者之间的解耦,它弥补了面向对象编程在跨越模块行为上的不足。AOP引进了Aspect概念,它将多个类的重复代码封装到一个可重用模块中,允许程序员把横切关注点模块化,进而消除面向对象编程所引起的代码混乱和分散问题,增强系统的可维护性和代码的可重用性,如安全、事务、日志等横切关注。当系统开发变得越来越庞大时,就可以使用AOP轻松解决横切关注点和调用者和被调用者之间的解耦问题。

   AOP是Spring框架的一个关键技术,它和Spring的IoC技术一样重要,虽然AOP进一步完善了Spring的IoC容器,但Spring的IoC容器并不依赖于AOP,这就意味着如果没有必要可以不使用它。主要的功能是:日志记录,性能统计,权限管理,事务处理,异常处理等等。

以上都是摘要于:http://blog.csdn.net/hanzhou4519/article/details/7704245http://blog.csdn.net/wuyueyuljh/article/details/7475132

使用AOP就必须先配置AOP。今天就因为没有配置好AOP而纠结了一天。还好csdn的牛人的心肠好。配置如下,我用的myeclipse8.6,可以通过myeclipse的工具自动导入jar包。选中项目,选MyEclipse ------->project capabilities------>add Spring capabilities..然后选择版本。并把核心库和AOP的库都加进来。就可以省略自己导包了。但是我今天自己导包反而不能出来。所以。还是建议用工具吧。就因为这个,我悲剧了一天呢。

然后就可以在applicationContext.xml中配置了。

	<bean id="userdaoImp" class="imp.UserDaoImpl"></bean>
    <bean id="aop" class="aop.CreateAop"></bean>
    <aop:config>
        <!-- 配置切面 -->
        <aop:aspect id="ap" ref="aop">
            <!-- 配置切入点 :expression={返回任意类型或不返回 ,这个包下的任意类的任意方法和任意参数}-->
            <!-- <aop:pointcut expression="execution(* imp.*.*(String))" id="ep"/> 这个String表示只能传一个String的参数,如果不匹配将不执行这个方法-->
             <aop:pointcut expression="execution(* imp.*.*(..))" id="ep"/>
            <!-- 配置通知 -->
            <aop:after method="doAfter" pointcut-ref="ep"/>    <!--执行方法之前的动作-->
            <aop:before method="doBeofore" pointcut-ref="ep"/><!--执行方法之后的动作-->
            <aop:around method="doAround" pointcut-ref="ep"/><!--每个方法都执行的动作,环绕通知-->
            <aop:after-throwing method="doException" pointcut-ref="ep" throwing="ex"/><!--抛异常后的通知-->
        </aop:aspect>
    </aop:config>

然后要写一个切面类:对了这个切面类应该是最写的。这就不做排序了。

public class CreateAop {
	//在方法之前执行的动作
	public void doBeofore(JoinPoint jointPoint){
		System.out.println("--------权限验证");
		
		//获取执行之前的类的信息
		System.out.println("方法执行的类:"+jointPoint.getTarget().getClass().getName());
		System.out.println("执行的方法:"+jointPoint.getSignature().getName());
		System.out.print("执行的参数有:");
		Object obj[]=jointPoint.getArgs();
		for(int i=0;i<obj.length;i++){
			System.out.print(" "+obj[i]+" ");
		}
	}
	//在方法之后执行的动作
	public void doAfter(JoinPoint jointPoint1){
		System.out.println("--------记录日志");
		//获取执行之前的类的信息
		StringBuffer sb=new StringBuffer();
		sb.append(jointPoint1.getTarget().getClass().getName());
		sb.append(".");
		sb.append(jointPoint1.getSignature().getName());
		sb.append("(");
		
		Object obj[]=jointPoint1.getArgs();
		if(obj.length>0){
			for(int i=0;i<obj.length-1;i++){
				sb.append(obj[i]);
				sb.append(",");
			}
			sb.append(obj[obj.length-1]);
		}
		sb.append(")");
		System.out.println(sb.toString());
	}
	//环绕通知
	public void doAround(ProceedingJoinPoint pjp){
		long time=System.currentTimeMillis();
		try {
			pjp.proceed();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		long time1=System.currentTimeMillis();
		System.out.println("方法执行了"+(time1-time)+"毫秒");
	}
	//抛出异常通知
	public void doException(JoinPoint jointPoint,Exception ex){
		if(ex!=null){
			this.sendMsg();
		}
		System.out.println("抛异常了");
	}
	public void sendMsg(){
		System.out.println("老板,抛异常了。。。");
	}
}

这里有一个bug就是抛异常后:本想让人执行sendMsg方法。但是就是不执行。。希望能有人够想想告诉我吧。。谢谢了。

这里的两个接口和实现类就不写了。AOP最主要的地方就是配置文件和切面类了。测试的时候:注意;

		//XmlBeanFactory不支持AOP
//		ClassPathResource cpr=new ClassPathResource("applicationContext.xml");
//		XmlBeanFactory factory=new XmlBeanFactory(cpr);
//		UserDao userdao=(UserDao)factory.getBean("userdaoImp");
//		userdao.insert("young");
		
		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao userdao=(UserDao)factory.getBean("userdaoImp");
		userdao.insert("young");
		
		System.out.println("************************");
		userdao.test();
XmlBeanFactory不支持AOP。今天就先写到这吧。明天继续学习。
使用注解配置AOP:那配置文件中就不用配置AOP了。只需配置aop类和实现类就行了。
@Aspect		//配置切面
public class CreateAop implements ThrowsAdvice {
	@Pointcut("execution(* imp.*.*(..))")		//配置切入点
	private void apMethod(){}
	
	@Before("apMethod()")
	public void doBeofore(JoinPoint jointPoint){//在方法之前执行的动作
		System.out.println("--------权限验证");
		
		//获取执行之前的类的信息
//		System.out.println("方法执行的类:"+jointPoint.getTarget().getClass().getName());
//		System.out.println("执行的方法:"+jointPoint.getSignature().getName());
//		System.out.print("执行的参数有:");
//		Object obj[]=jointPoint.getArgs();
//		for(int i=0;i<obj.length;i++){
//			System.out.print(" "+obj[i]+" ");
//		}
		System.out.println("日志记录:(方法执行后)类名:"+jointPoint.getTarget().getClass().getName()+"\t"+"方法名:"+jointPoint.getSignature().getName()+"\t");
		System.out.print("参数:");
		Object obj[] =jointPoint.getArgs();
		for(Object object:obj){
			System.out.print(object+"  ");
		}
	}
	
	@After("apMethod()")
	public void doAfter(JoinPoint jointPoint1){//在方法之后执行的动作
		System.out.println("--------记录日志");
		//获取执行之前的类的信息
		StringBuffer sb=new StringBuffer();
		sb.append(jointPoint1.getTarget().getClass().getName());
		sb.append(".");
		sb.append(jointPoint1.getSignature().getName());
		sb.append("(");
		
		Object obj[]=jointPoint1.getArgs();
		if(obj.length>0){
			for(int i=0;i<obj.length-1;i++){
				sb.append(obj[i]);
				sb.append(",");
			}
			sb.append(obj[obj.length-1]);
		}
		sb.append(")");
		System.out.println(sb.toString());
	}
	
	@Around("apMethod()")
	public void doAround(ProceedingJoinPoint pjp){//环绕通知
		long time=System.currentTimeMillis();
		try {
			pjp.proceed();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		long time1=System.currentTimeMillis();
		System.out.println("方法执行了"+(time1-time)+"毫秒");
	}
	
	@AfterThrowing(pointcut=("apMethod()"),throwing="e")
	public void doThorwing(JoinPoint jointPoint,Throwable e){//抛出异常通知
//		System.out.println(e.getMessage());
		this.sendMsg(e.getMessage());
	}
	public void sendMsg(String ex){
		if(ex!=null){
			System.out.println("老板,抛异常了。。。");
		}
	
	}

抱歉!评论已关闭.