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

来源:互联网 发布:java 字符串查找 编辑:程序博客网 时间:2024/06/02 19:57

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

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

以上都是摘要于:http://blog.csdn.net/hanzhou4519/article/details/7704245和http://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 blocke.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 blocke.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("老板,抛异常了。。。");}}