专栏首页别先生Spring之注解实现aop(面向切面编程)

Spring之注解实现aop(面向切面编程)

1:Aop(aspect object programming)面向切面编程,名词解释:     1.1:功能:让关注点代码与业务逻辑代码分离     1.2:关注点         重复代码就叫做关注点     1.3:切面         关注点形成的类,就叫做切面(类)         面向切面编程,就是指对很多功能都有的重复代码抽取,再在运行的时候往业务方法上动态植入"切面类代码";     1.4:切入点         执行目标对象方法,动态植入切面代码         可以通过切入点表达式,指定拦截那些类的那些方法,给指定的类在运行的时候植入切面类代码; 2:注解方式实现aop编程     2.1:开发步骤         (1):先引入aop相关的jar文件             spring-aop-3.2.5.RELEASE.jar【去spring3.2源码里面找】             aopalliance.jar【去spring2.5源码/lib/aopalliance文件里面找】             aspectjweaver.jar【去spring2.5源码/lib/aspectj文件里面找】或者【aspectj-1.8.2/lib/aspectjweaver.jar】             aspectjrt.jar【去spring2.5源码/lib/aspectj文件里面找】或者【aspectj-1.8.2/lib/aspectjrt.jar】

《注意:用到的spring2.5版本的jar本舰,如果用jd1.7版本可能会出现问题,               需要升级以下aspectj组件,即使用aspectj-1.8.2版本中提供的jar文件aspectjweaver.jar和aspectjrt.jar》            (2)bean.xml中引入aop名称空间 技巧:找到文件spring-framework-3.2.5.RELEASE/docs/spring-framework-reference/htmlsingle 打开index.html搜索xmlns:aop然后找到下面红色三句话,分别拷贝到bean.xml中 <?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.xml如下所示:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:p="http://www.springframework.org/schema/p"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xmlns:aop="http://www.springframework.org/schema/aop"
 7     xsi:schemaLocation="
 8         http://www.springframework.org/schema/beans
 9         http://www.springframework.org/schema/beans/spring-beans.xsd
10         http://www.springframework.org/schema/context
11         http://www.springframework.org/schema/context/spring-context.xsd
12         http://www.springframework.org/schema/aop
13         http://www.springframework.org/schema/aop/spring-aop.xsd">
14 
15 </beans> 

(3):bean.xml中开启aop注解扫描,如下配置所示:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:p="http://www.springframework.org/schema/p"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xmlns:aop="http://www.springframework.org/schema/aop"
 7     xsi:schemaLocation="
 8         http://www.springframework.org/schema/beans
 9         http://www.springframework.org/schema/beans/spring-beans.xsd
10         http://www.springframework.org/schema/context
11         http://www.springframework.org/schema/context/spring-context.xsd
12         http://www.springframework.org/schema/aop
13         http://www.springframework.org/schema/aop/spring-aop.xsd">
14 
15       <!-- 开启注解扫描 -->
16       <context:component-scan base-package="com.bie.aop"></context:component-scan>   
17         
18       <!-- 开启aop注解方式,默认为false -->    
19       <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
20       
21 </beans>        

 (4):开始写一个切面类,源码如下所示:

 1 package com.bie.aop;
 2 
 3 import org.aspectj.lang.annotation.After;
 4 import org.aspectj.lang.annotation.Aspect;
 5 import org.aspectj.lang.annotation.Before;
 6 import org.aspectj.lang.annotation.Pointcut;
 7 import org.springframework.stereotype.Component;
 8 
 9 
10 /** 
11 * @author BieHongLi 
12 * @version 创建时间:2017年3月28日 下午9:10:43 
13 * @Aspect:指定当前类为切面类
14 */
15 @Component  //加入到IoC容器
16 @Aspect  //指定当前类为切面类
17 public class Aop {
18 
19     //指定切入点表达式,拦截那些方法,即为那些类生成代理对象
20     //@Pointcut("execution(* com.bie.aop.UserDao.save(..))")  ..代表所有参数
21     //@Pointcut("execution(* com.bie.aop.UserDao.*())")  指定所有的方法
22     //@Pointcut("execution(* com.bie.aop.UserDao.save())") 指定save方法
23     
24     @Pointcut("execution(* com.bie.aop.UserDao.*(..))")
25     public void pointCut(){
26         
27     }
28     
29     @Before("pointCut()")
30     public void begin(){
31         System.out.println("开启事务");
32     }
33     
34     @After("pointCut()")
35     public void close(){
36         System.out.println("关闭事务");
37     }
38     
39 }

 (5):写好切面类就可以写执行目标对象方法,接口和实现类如下所示:

 1 package com.bie.aop;
 2 
 3 /** 
 4 * @author BieHongLi 
 5 * @version 创建时间:2017年3月28日 下午9:09:29 
 6 * 
 7 */
 8 
 9 public interface IUserDao {
10 
11     public void save();
12 }
 1 package com.bie.aop;
 2 
 3 
 4 import org.springframework.stereotype.Component;
 5 
 6 /** 
 7 * @author BieHongLi 
 8 * @version 创建时间:2017年3月28日 下午9:09:53 
 9 * 目标对象
10 */
11 @Component
12 public class UserDao implements IUserDao{
13     
14     @Override
15     public void save() {
16         System.out.println("..核心业务--核心业务..");
17     }
18 
19     
20 }

 (6):最后就可以进行进行测试了,源码如下所示:

 1 package com.bie.aop;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 /** 
 8 * @author BieHongLi 
 9 * @version 创建时间:2017年3月28日 下午9:13:18 
10 * 
11 */
12 public class AopTest {
13 
14     ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
15     
16     //目标对象有实现接口,spring会自动选择"jdk代理【动态代理】"
17     //动态代理的标识:class com.sun.proxy.$Proxy10
18     @Test
19     public void test01(){
20         IUserDao dao =  (IUserDao) ac.getBean("userDao");
21         System.out.println(dao.getClass());
22         dao.save();
23     }
24     
25     
26     //class com.bie.aop.OrderDao$$EnhancerByCGLIB$$4952a60a
27     //目标对象没有实现接口,spring会用"cglib代理哦"
28     @Test
29     public void testCglib(){
30         OrderDao dao =  (OrderDao) ac.getBean("orderDao");
31         System.out.println(dao.getClass());
32         dao.save();
33     }
34 }

  3:心得体会和报错解决:

    3.1:虽然案例很简单很简单,但是我花了三四个小时,为什么呢!我用junit测试spring写的注解实现aop(面向切面编程)。

    3.2:编辑环境:eclipse+tomcat8.0+jdk1.8,为什么说编辑环境呢,因为jdk1.8和spring好像有仇似的,开始我安装的jdk是1.8版本的,总之包很多很多错,主要的caused by:java.lang.IllegalArgumentException【看错误主要看caused by】

    3.3:这个错是UserDao dao =  (UserDao) ac.getBean("userDao");---》

        IUserDao dao =  (IUserDao) ac.getBean("userDao");

        意思就是说必须使用接口来接受从IoC容器获取的,不能使用实现类接受,不然报的错够你喝一壶了

java.lang.ClassCastException: com.sun.proxy.$Proxy10 cannot be cast to com.bie.aop.UserDao     at com.bie.aop.AopTest.test01(AopTest.java:18)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     at java.lang.reflect.Method.invoke(Method.java:606)     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)     at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)     at org.junit.runners.ParentRunner.run(ParentRunner.java:363)     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

 3.4:然后呢,我就思考就要换成jdk1.7,我去oracle官网搜了,已经没了jdk1.7,我又去我的百度云翻出1.7,然后安装,之后呢,我就验证呗,其实安装之前我也思考过,能不能安装1.8之后再安装1.7,安装肯定没毛病啊,但是总要配置环境变量吧,我就配置jdk1.7之后发现验证的时候还是显示是jdk1.8,我就赶紧思考啊,思考过后我考虑应该把jdk1.7,jdk1.8都卸载了,然后我都卸载了,然后重新安装jdK1.7,之后配置之后,其实主要给Java_home环境变量改一下就行,然后验证就显示jdk1.7版本了,之后呢又去测试程序,然而呢,程序之前是jdk1.8,全部报错了,我又把jdk1.8换成1.7;详细更换jdk1.8--->jdk1.7的过程如下所示;

首先,第一步:点击window-->Preferences-->Java-->Installed JREs-->ADD

第二步:点击add之后显示如下所示

第三步:点击next之后点击如下图所示的Directory即可;

第四步:点击项目右击

第五步:如下所示

第六步:如下所示

第七步:如下所示

第八步:如下所示

第九步:如下所示

然后呢,jdk总算是由jdk1.8换成了1.7,这个过程虽然比较麻烦,但是解决问题,我也很开心啊,加油吧,骚年~~~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Spring之配置文件bean作用域的详细介绍

    Spring的配置文件applicationContext.xml中bean作用域的详细介绍: 1:对象的创建:单例和多例         scope="sin...

    别先生
  • SpringCloud的入门学习之深入理解Eureka注册中心

      答:a、Eureka Server,注册中心,通过 Register、Get、Renew 等接口提供服务的注册和发现。     b、Application ...

    别先生
  • Spring之hello world(Spring入门)

    spring各个版本中: 在3.0以下的版本,源码有spring中相关的所有包【spring功能 + 依赖包】 如2.5版本; 在3.0以上的版本,源...

    别先生
  • SSH框架之Spring第三篇

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    海仔
  • springmvc带你学:带你入门

    传统MVC——>JSPModel2——>Front Controller + Application Controller + Page Controller ...

    好好学java
  • Spring:AOP 面向切面编程

    上面的代码事务在 Dao 层,转出转入操作都是一个独立的事务,但实际开发,应该把业务逻辑控制在一个事务中,所以应该将事务挪到 Service 层。

    RendaZhang
  • 腾讯研究院“互联网+”案例研究组赴河北大城调研

    ? ◢ 腾讯研究院研究员及大城县相关政府部门人员与企业座谈   7月12日,腾讯研究院“互联网+”案例研究小组一行到河北大城县进行调研,就“互联网+产业”、“...

    腾讯研究院
  • Kubernetes持久卷实战两部曲之一:极速体验

    整个《Kubernetes持久卷实战》由以下两篇文章组成: 1. 极速体验静态持久化存储,也就是本章的内容; 2. 了解k8s的pod、service、...

    程序员欣宸
  • 国泰航空 940 万名乘客个人数据在 3 月被盗 包含出行地点数据

    据外媒报道,日前大型国际航空公司国泰航空披露,在今年3月发生的一次数据泄露事件中,该公司的940万名乘客的记录被盗,另外含有姓名、出生日期、住址等个人信息的护照...

    C4rpeDime
  • JS中3种风格的For循环有什么异同?

    在学习任何开发语言时候,for循环是必不可少的一种语法,可能所有开发人员都会使用它。它非常经典,以至于每个开发语言都至少包括一种关于循环的语法版本。不过,在Ja...

    葡萄城控件

扫码关注云+社区

领取腾讯云代金券