Spring(四)

SpringAOP

       AOP表示面向切面编程,它是面向对象编程(OOP)的一种补充

       在传统编程当中,需要进行事务处理,日志记录等操作,oop可以通过继承等方式来达到代码重用

       AOP采用横向抽取机制,将分散在各个地方的重复代码提取出来,然后再程序编译或运行时,再将这些提取出来的代码应用到需要执行的地方。

       AOP术语:

       Aspect(切面):在实际应用中,切面通常是指封装的用于横向插入系统功能的类

       Joinpoint(连接点):在程序执行过程中的某个阶段点,他实际上是对象的一个  操作,例如方法的调用和异常抛出

       Pointcut(切入点):是指切面与程序流程的交叉点,切入点指类或者方法名

       Advice(通知/增强):AOP框架在特定的切入点执行的增强处理,即在定义好的切入点处所要执行的程序代码。

       TargetObject(目标对象):是指所有被通知的对象,也称为被增强对象

       Proxy(代理):将通知应用到目标对象之后,被动态创建的对象

       Weaving(织入):将切面代码插入到目标对象上,从而生成代理对象的过程

       JDK动态代理:

              JDK动态代理是通过java.lang.reflect.Proxy类来实现的,可以调用Proxy类的newProxyInstance()方法来创建代理对象

              实现步骤:

              编写接口

             

              编写实现类

             

              编写切入类

              // 切面类 

public class MyAspect {

       // 以下方法称为增强方法

       public void method1() {

              System.out.println("检查账号是否正确");

       }

 

       public void method2() {

              System.out.println("通过检查...");

       }

      

      

      

 

}

              编写代理类

              public class jdkProxy implements InvocationHandler {

 

       // 声明目标接口

       private UserDao userDao;

      

       // 创建代理方法

       public Object createProxy(UserDao userDao){

              this.userDao = userDao;

             

              // 1、类加载器

              ClassLoader classLoader = jdkProxy.class.getClassLoader();

              // 2、被代理对象实现的所有接口

              Class[] claqq = userDao.getClass().getInterfaces();

              // 3、使用代理类,进行增强,返回的事代理后的对象

              return Proxy.newProxyInstance(classLoader, claqq, this);

             

             

       }

      

       /*

        *

        *   所有动态代理类的方法调用,都会交由invoke()方法处理

        *   proxy表示被代理后的对象

        *   method将要被执行的方法信息(通过反射处理)

        *   args执行方法是需要的参数

        *

        *

        */

       @Override

       public Object invoke(Object proxy, Method method, Object[] args)

                     throws Throwable {

              // TODO Auto-generated method stub

              // 声明切面

              MyAspect myAspect = new MyAspect();

              // 前增强

              myAspect.method1();

              // 在目标类上调用方法,并传入参数

              Object obj = method.invoke(userDao, args);

              // 后增强

              myAspect.method2();

              return obj;

       }

 

}

              编写测试类

              @Test

       public void method(){

              // 创建代理对象

              jdkProxy jdkProxy = new jdkProxy();

              // 创建目标对象

              UserDao userDao = new UserDaoImpl();

              // 从代理对象中获取增强后的目标对象

              UserDao userDao1 = (UserDao) jdkProxy.createProxy(userDao);

              // 执行方法

             

              userDao.addUser();

              userDao.deleteUser();

             

             

              System.out.println("==============================================");

             

             

              userDao1.addUser();

              userDao1.deleteUser();

       }

 

              将jdk动态代理模式改装成springAop

              去掉代理类由spring接管

              更改切面类MyAspect

              // 切面类 

public class MyAspect implements MethodInterceptor{

       // 以下方法称为增强方法

       public void method1() {

              System.out.println("检查账号是否正确");

       }

 

       public void method2() {

              System.out.println("通过检查...");

       }

      

      

       // 此时代理方法在这里

       @Override

       public Object invoke(MethodInvocation mi) throws Throwable {

              // TODO Auto-generated method stub

              method1();

              // 执行目标方法

              Object obj = mi.proceed();

              method2();

             

              return obj;

       }

 

}

              编写配置文件

              <!-- 1、目标类 -->

       <bean id="userDao" class="com.bdqn.cn.dao.UserDaoImpl" />

      

       <!-- 2、定义切面类 -->

       <bean id="myAspect" class="com.bdqn.cn.aspect.MyAspect" />

      

       <!-- 3、使用Spring代理工厂定义一个名称为userDaoProxy的代理对象 -->

       <bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

             

              <!-- 指定代理实现的接口 -->

              <property name="proxyInterfaces" value="com.bdqn.cn.dao.UserDao" />

              <!-- 指定目标对象 -->

              <property name="target" ref="userDao" />

              <!-- 指定切面植入环绕通知 -->

              <property name="interceptorNames" value="myAspect" />

              <!-- 指定代理方式,默认使用jdk动态代理  如果value值为true表示使用cglib-->

              <property name="proxyTargetClass" value="false" />

                    

       </bean>

              编写测试类

              @Test

       public void method2(){

             

              ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");

              UserDao ud = (UserDao)app.getBean("userDaoProxy");

              ud.addUser();

              ud.deleteUser();

             

       }

 

 

发布了40 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/sj_1993/article/details/105249918