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中

         

         <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

Image

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

Image

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

Image

第四步:点击项目右击

Image

第五步:如下所示

Image

第六步:如下所示

Image

第七步:如下所示

Image

第八步:如下所示

Image

第九步:如下所示

Image

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

本文内容总结:Spring之注解实现aop(面向切面编程)

原文链接:https://www.cnblogs.com/biehongli/p/6640406.html

以上是 Spring之注解实现aop(面向切面编程) 的全部内容, 来源链接: utcz.com/z/296882.html

回到顶部