Spring aop

Spring  aop

 Aop:面向切面编程,纵向重复,横向抽取


代理:生活中的例子:找明星拍戏。上综艺,唱歌,直接找明星说明这个明星太小了。如果明星有点名气,那就不直接访问了,

必须先同过访问明星的经纪人,然后经纪人访问明星。放在程序当中,有一个目标对象有一个代理对象。你想要访问目标对象,必须先通过代理对象访问目标对象。Java提供了一个类proxy能实现代理。



Spring AOP

   利用了代理技术  解决主要用于service层的事务管理



Spring  实现aop有两种方法:

   (1)动态代理

               被代理对象必须有接口,如果没有接口咋不能实现动态

   (2)cglib代理:

                 第三方的代理计技术。任何类都可以实现代理,使用继承的机制实现代理,所以被代理不能被final修饰。


             手动实现动态代理:

                 准备一个UserService  UserServiceImpl

                 准备一个获得UserService代理对象的类

   1.获得代理对象  通过调用proxy的newProxyInstance方法 传递三个参数

       ①本类的加载器  ②代理对象的接口(实现获得的接口)③this.      这样就得到一个代理对象

    2.实现代理对象的方法,让这个类 实现Invocation接口 实现他的方法invoke(代理对象,调用的方法,方法的参数)

  

     3.被代理对象还要被调用,所有调用metho.invoke()两个参数,一个是被代理的对象,参数 是给该类加上一个属性被代理对象,并给该类添加构造函数。在调用被代理对象前后,可以加上对象的内容

public class UserServiceProxyFactory implements InvocationHandler {

    private UserService userService;

    public UserServiceProxyFactory(UserService userService) {
        this.userService = userService;
    }

    public UserService getUserServiceProxy() {
        /*getClassLoader()类加载器,getInterfaces()       得到代理对象*/
        UserService userServiceProxy = (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(), UserServiceImpl.class.getInterfaces(), this);
        return userServiceProxy;
    }

    @Override
    /*proxp:代理对象

    参数:被代理的对象,被代理的方法,参数
    *
    * */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开启事务");
        /*调用被代理对象的方法*/
        Object invoke = method.invoke(userService, args);
        System.out.println("提交事务");
        return invoke;
    }
}

 cglib代理

   

public class UserServiceProxyFactory2 implements MethodInterceptor{


    public UserService getUserServiceProxy() {

         /*帮助我们生成代理对象 */
        Enhancer enhancer=new Enhancer();
        /*设置对谁进行代理*/
        enhancer.setSuperclass(UserServiceImpl.class);
        /*设置回调方法*/
        enhancer.setCallback(this);

        UserService userServiceProxy = (UserService) enhancer.create();

        return userServiceProxy;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("开启事务");
        Object o1 = methodProxy.invokeSuper(o, objects);
        System.out.println("关闭事务");
        return o1;
    }
}

                                         Spring AOP配置

 


    1.导包(4+2    +2+2  spring(aop aspect) spring依赖包())

    2.准备目标对象 userServiceImpl

     3.准备通知

     4.配置applicatContext.xml文件

             导入约束:

                     直接打入<aop:Conf 如果有提示 直接回车 自动帮你导  没有提示的话就手动导入>

              配置切入:

             

<aop:pointcut id="pc" expression="execution(目标对象要增强的方法)     "></aop:pointcut>

              配置切面:将通知织入到对应的切入点

                     

<aop:aspect ref="方法">
 

               多种方式切入:

                总共有五种切入方式

                              ①在目标方法前调用

                                    Aop:before

                                  ②在目标对方法后调用

                                    Aop:afterReruming

                                    ③在目标对象方法后调用(不管有没有异常)

                                           aop:after

                                    ④在目标对象前后调用代码(特殊,在通知中的方法proceedingJoinPoint参数)如果有异常后方法不                                         调用

                                            Aop:around

                                        ⑤只在目标方法出现异常时调用

                                                 

                                             Aop:after-thoreing



                         <aop:before methor="通知增强的方法" pointcut-ref="切入点"><aop:before/>

    <aop:config>
             <!--配置切入点-->
        <!-- public  void     cn.hd.SpringProxy.impl.UserServiceImpl.add()
              省略    返回值*   cn.hd.SpringProxy.impl.UserServiceImpl.add()
                               cn.hd.SpringProxy.impl.UserServiceImpl.*(..) //所有方法可以用*代替所有参数用
                                cn.hd.SpringProxy.impl.*ServiceImpl.*(..)

        -->
        <aop:pointcut id="pc" expression="execution(* cn.hd.SpringProxy.impl..*UserServiceImpl.*(..))"></aop:pointcut>
      <!--配置切面 植入通知-->
        <aop:aspect ref="myAdvice">

         <!--   <aop:before method="after" pointcut-ref="pc"></aop:before>-->
   <!--         <aop:after method="after" pointcut-ref="pc"></aop:after>-->
            <!--环绕调用 如果有异常 则不调用围绕后的方法-->
           <!-- <aop:around method="around" pointcut-ref="pc"></aop:around>-->
            <!--出了一场就不调用-->
          <!--  <aop:after-returning method="afterReturning" pointcut-ref="pc"></aop:after-returning>
        -->

            <!--出现异常了才调用-->
        <aop:after-throwing method="throwException" pointcut-ref="pc"></aop:after-throwing>

        </aop:aspect>

                                        


                                                                       使用注解的方式配置AOP(了解)

                     1.开启注解模式:

                        

                               <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

                        2.注解切面

                                    

                            在通知上面加上一个注解

                            

                                                  @Component("myAdvice")
                                                    @Aspect

                                                    public class MyAdvice {


                                       再通知的方法上面加上切点

                                       

                                           五种

                                          

                @Before(表达式)  @After  @AfterReturning   @Around   @AfterThrowing

               

                                         

 

@Before("MyAdvice.pc()")
public void before(){
    System.out.println("在目标方法前调用");
}

            ①直接写

        

          ②配置一个切点,调用类的方法获得的切点

              

@Pointcut("execution(* cn.hd.springProxyAnnoation.impl.UserServiceImpl.*(..))")
public  void pc(){



}

@Before("MyAdvice.pc()")
public void before(){
    System.out.println("在目标方法前调用");
}

 

                                          

                              

 




 


    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值