码迷,mamicode.com
首页 > 其他好文 > 详细

2018.3.10(动态代理 增强)

时间:2018-03-10 11:56:58      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:测试   pre   out   targe   path   res   size   xmla   对象   

JDK动态代理:

     准备一个接口ISomeService,接口中有一个方法doSome(),和一个这个接口的实现类SomeServiceImpl,并重写其中的方法

public interface ISomeService
{
    public void doSome();
}


public class SomeServiceImpl implements ISomeService {
    public void doSome() {
        System.out.println("我不是好人");
    }
}

使用JDK动态代理不需要再配置文件中进行配置,所以现在直接进行测试,但是测试的时候不能使用单测,而是使用main方法进行测试

public class Test {
    public static void main(String[] args) {
        //首先创建一个接口的实现类
        final SomeServiceImpl service=new SomeServiceImpl();
        //在调用方法之前想使用动态代理记录一下日志,生成动态代理,返回的是接口
        ISomeService proxyInstance =(ISomeService) Proxy.newProxyInstance(service.getClass().getClassLoader(),
                service.getClass().getInterfaces(), new InvocationHandler() {
                    /**
                     *
                     * @param proxy  代理对象
                     * @param method  目标类型的方法
                     * @param args  方法的参数
                     * @return
                     * @throws Throwable
                     */
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //在这里记录一下日志
                        System.out.println("before=====");
                        //调用method 的
                        method.invoke(service,args);//相当于执行目标类型的方法
                        System.out.println("after=======");
                        return null;
                    }
                });

        //调用动态代理中的方法中的方法
        proxyInstance.doSome();
    }
}
CGLIB动态代理

public class Test {
    public static void main(String[] args) {
        final SomeServiceImpl service=new SomeServiceImpl();
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(service.getClass());
        enhancer.setCallback(new MethodInterceptor() {
            /**
             *
             * @param o 代理对象
             * @param method 目标类型的方法
             * @param objects 目标方法的参数
             * @param methodProxy 代理类的方法   是一个新的参数
             * @return
             * @throws Throwable
             */
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("before=====");
                methodProxy.invoke(service,objects);
                System.out.println("after=====");
                return null;
            }
        });
        SomeServiceImpl proxy =(SomeServiceImpl) enhancer.create();
        proxy.doSome();
    }
}



四中增强: 前置增强  后置增强  环绕增强  异常增强

接口和实体类
public interface ISomeService {
    public void doSome();
}

public class SomeServiceImpl implements ISomeService {
    public void doSome() {
        System.out.println("==A==");
    }
}

前置增强
public class BeforeAdvice implements MethodBeforeAdvice {
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("=========before");
    }
}

配置:
<bean id="service" class="demo10.SomeServiceImpl"></bean>
    <bean id="beforeAdvice" class="demo10.BeforeAdvice"></bean>
    <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="service"></property>
        <property name="interceptorNames" value="beforeAdvice"></property>
    </bean>

 测试类:

@Test
    public void t1(){
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextBefore.xml");
        ISomeService proxyService =(ISomeService) context.getBean("proxyService");
        proxyService.doSome();
    }
后置增强:
<bean id="service" class="demo11.SomeServiceImpl"></bean>
    <bean id="afterAdvice" class="demo11.AfterAdvice"></bean>
    <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="service"></property>
        <property name="interceptorNames" value="afterAdvice"></property>
    </bean>

环绕增强

直接引用上面的接口和实现类  再创建另一个类 MethodAdvice

public class MethodAdvice implements MethodInterceptor {
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("前置增强");
        Object result = methodInvocation.proceed();
        System.out.println("后置增强");
        return result;
    }
}

配置:
 <bean id="service" class="demo12.SomeServiceImpl"></bean>
    <bean id="methodAdvice" class="demo12.MethodAdvice"></bean>
    <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="service"></property>
        <property name="interceptorNames" value="methodAdvice"></property>
    </bean>
 
异常增强
public class MyThroesAdvice implements ThrowsAdvice {
    public void afterThrowing(Exception ex){
        System.out.println("网络出现错误");
    }
}

配置:
 <bean id="service" class="demo13.SomeServiceImpl"></bean>
    <bean id="throwsAdvice" class="demo13.MyThroesAdvice"></bean>
    <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="service"></property>
        <property name="interceptorNames" value="throwsAdvice"></property>
    </bean>

 测试类:

@Test
   public void t2(){
       ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextThrows.xml");
       ISomeService proxyService =(ISomeService) context.getBean("proxyService");
       try{
           proxyService.doSome();
       }catch (Exception ex){
           ex.printStackTrace();
       }

advisor

配置类:
<bean id="service" class="demo14.SomeServiceImpl"></bean> <bean id="beforeAdvice" class="demo14.BeforeAdvice"></bean> <!--与其他不一样的地方--> <bean id="advisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice" ref="beforeAdvice"></property> <property name="mappedNames" value="do*"></property> </bean> <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="service"></property> <property name="interceptorNames" value="advisor"></property> </bean>

测试类:
@Test
   public void t2(){
       ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextAdvisor.xml");
       ISomeService proxyService =(ISomeService) context.getBean("proxyService");
       proxyService.doSome();
       proxyService.doAny();
   }





2018.3.10(动态代理 增强)

标签:测试   pre   out   targe   path   res   size   xmla   对象   

原文地址:https://www.cnblogs.com/xu06123/p/8537372.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!