首页 技术 正文
技术 2022年11月15日
0 收藏 779 点赞 3,791 浏览 9328 个字

1,动态代理,指的是通过一个代理对象创建需要的业务对象,然后在这个代理对象中统一进行各种操作。

步骤:

1)写一个类实现InvocationHandler接口;

2)创建要代理的对象

2,创建一个简单的打印日志的类Logger

package com.yangw.spring.proxy;import java.util.Date;public class Logger {    public static void info(String msg){        System.out.println(new Date()+"----"+msg);    }}

3,自定义注解类

package com.yangw.spring.model;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public @interface LogInfo {    public String value() default "";}

4,自定义动态代理类LogProxy

package com.yangw.spring.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import com.yangw.spring.model.LogInfo;/** * 1 写一个类,实现InvocationHandler接口 * @author Administrator * */public class LogProxy implements InvocationHandler {    //2,创建代理对象    private Object target;    private LogProxy(){};    //3,创建一个方法来生成代理对象,这个方法的参数是要代理的对象    public static Object getInstance(Object obj){        //3.1  创建LogProxy对象        LogProxy proxy=new LogProxy();        //3.2 设置代理对象        proxy.target=obj;        //3.3 通过Proxy.newProxyInstance()创建代理对象        //参数1:要代理对象的classloader,参数2:要代理对象的实现的所有接口,        //参数3:实现InvocationHandler接口的对象        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),                obj.getClass().getInterfaces(), proxy);    }    /**     * 当有了代理对象之后,都会调用下面的invoke()方法     */    @Override    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {        //这里怎么处理完全由我们来控制的        /*if(method.getName().equals("add")|| method.getName().equals("delete")){            Logger.info("调用我...");        }*/        //只对有LogInfo注解的进行处理,        //而且是在method.invoke调用之前,调用之后执行都可以        //在异常中进行处理也可以        if(method.isAnnotationPresent(LogInfo.class)){            Logger.info(method.getAnnotation(LogInfo.class).value());        }            return method.invoke(target, args);        //aspect orient program (面向切面编程)    }}

5,在需要加入注解的接口上面加入自定义注解LogInfo

package com.yangw.spring.dao;import com.yangw.spring.model.LogInfo;import com.yangw.spring.model.User;public interface IUserDao {    @LogInfo("add a user")    public void add(User user) ;    @LogInfo("delete a user")    public void delete(int id) ;    public User load(int id);}

6,beans2.xml中的配置如下

<beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:context="http://www.springframework.org/schema/context"     xsi:schemaLocation="http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd         http://www.springframework.org/schema/context         http://www.springframework.org/schema/context/spring-context-3.0.xsd">   <!--1, 打开Spring的annotation -->   <context:annotation-config/>   <!-- 2, 设定Spring去那些包中找annotation -->    <context:component-scan base-package="com.yangw.spring" />    <!--用代理类实现        对于静态(static)的注入,使用factory-method    -->    <bean id="userDynamicDao" class="com.yangw.spring.proxy.LogProxy"          factory-method="getInstance">        <!--静态方法传入的参数 -->        <constructor-arg ref="userDao" />    </bean>    <!-- 依次加入想加入的    <bean id="msgDynamicDao" class="com.yangw.spring.proxy.LogProxy"          factory-method="getInstance">        <constructor-arg ref="MsgDao" />    </bean>    --></beans>

7,UserService类上注入userDynamicDao

package com.yangw.spring.service;import javax.annotation.Resource;import org.springframework.stereotype.Service;import com.yangw.spring.dao.IUserDao;import com.yangw.spring.model.User;@Service("userService")public class UserService implements IUserService {    @Resource(name="userDynamicDao")    private IUserDao userDao ;    @Override    public void add(User user) {        userDao.add(user);    }    @Override    public void delete(int id) {        userDao.delete(id);    }    @Override    public User load(int id) {        return    userDao.load(id);    }}

7, 测试

package com.yangw.spring.test;import org.junit.Test;import org.springframework.beans.factory.BeanFactory;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.yangw.spring.action.UserAction;import com.yangw.spring.model.User;public class TestSpring {     //1,创建Spring工厂    BeanFactory factory= new ClassPathXmlApplicationContext("beans2.xml");    @Test    public void testUser(){        //2,通过工厂获取Spring的对象        UserAction userAction = factory.getBean("userAction", UserAction.class);        User u1=new User(1,"yangw");        userAction.setUser(u1);        userAction.add();        userAction.delete();        userAction.load();    }}

8, Spring实现动态代理(基于annotation方式)

导入aopalliance-1.0.jar aspectjrt-1.6.10.jar aspectjweaver-1.7.2.jar 三个包,Spring使用这三个包实现AOP

<beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:context="http://www.springframework.org/schema/context"     xmlns:aop="http://www.springframework.org/schema/aop"     xsi:schemaLocation="http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd         http://www.springframework.org/schema/context         http://www.springframework.org/schema/context/spring-context-3.0.xsd            http://www.springframework.org/schema/aop         http://www.springframework.org/schema/aop/spring-aop.xsd">   <!--1, 打开Spring的annotation -->   <context:annotation-config/>   <!-- 2, 设定Spring去那些包中找annotation -->   <context:component-scan base-package="com.yangw.spring" />   <!-- 打开基于annotation的aop自动代理 -->   <aop:aspectj-autoproxy /></beans>

切面类

package com.yangw.spring.proxy;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;@Component("logAspect") //交给Spring管理@Aspect //说明是一个切面类public class LogAspect {    //前置通知    // 第1个"*": 任意返回值    // 第2个"*": com.yangw.spring.dao包中的所有类    // 第3个"*": add*表示以add开头的所有方法    // "(..)"  : 表示方法参数是任意值    // "||"    : 可以用或表达式加入多个条件    /**     * 函数调用之前执行     */    @Before("execution(* com.yangw.spring.dao.*.add*(..))||"            +"execution(* com.yangw.spring.dao.*.delete*(..))||"            +"execution(* com.yangw.spring.dao.*.update*(..))")    public void logStart(JoinPoint jp){        System.out.println(jp.getTarget()); //得到执行的类        System.out.println(jp.getSignature().getName()); //得到执行的方法名        Logger.info("log start.");    }    /**     * 函数调用之后执行     */    @After("execution(* com.yangw.spring.dao.*.add*(..))||"            +"execution(* com.yangw.spring.dao.*.delete*(..))||"            +"execution(* com.yangw.spring.dao.*.update*(..))")    public void logEnd(JoinPoint jp){        System.out.println(jp.getTarget()); //得到执行的类        System.out.println(jp.getSignature().getName()); //得到执行的方法名        Logger.info("log end.");    }    /**     * 函数调用过程中执行     */    @Around("execution(* com.yangw.spring.dao.*.add*(..))||"            +"execution(* com.yangw.spring.dao.*.delete*(..))||"            +"execution(* com.yangw.spring.dao.*.update*(..))")    public void logAround(ProceedingJoinPoint pjp) throws Throwable{        Logger.info("log around start");        pjp.proceed(); //让程序往下执行        Logger.info("log around end.");    }}

测试

package com.yangw.spring.test;import org.junit.Test;import org.springframework.beans.factory.BeanFactory;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.yangw.spring.action.UserAction;import com.yangw.spring.model.User;public class TestSpring {     //1,创建Spring工厂    BeanFactory factory= new ClassPathXmlApplicationContext("beans3.xml");    @Test    public void testUser(){        //2,通过工厂获取Spring的对象        UserAction userAction = factory.getBean("userAction", UserAction.class);        User u1=new User(1,"yangw");        userAction.setUser(u1);        userAction.add();        userAction.delete();        userAction.load();    }}

测试结果

Mon Oct 21 19:13:29 CST 2013----log around startcom.yangw.spring.dao.UserDao@18ce14aaddMon Oct 21 19:13:29 CST 2013----log start.add :User [id=1, username=yangw]Mon Oct 21 19:13:29 CST 2013----log around end.com.yangw.spring.dao.UserDao@18ce14aaddMon Oct 21 19:13:29 CST 2013----log end.Mon Oct 21 19:13:29 CST 2013----log around startcom.yangw.spring.dao.UserDao@18ce14adeleteMon Oct 21 19:13:29 CST 2013----log start.delete :0Mon Oct 21 19:13:29 CST 2013----log around end.com.yangw.spring.dao.UserDao@18ce14adeleteMon Oct 21 19:13:29 CST 2013----log end.load :0null

9, Spring实现动态代理(基于xml方式) 一般这种用的多

导入aopalliance-1.0.jar aspectjrt-1.6.10.jar aspectjweaver-1.7.2.jar 三个包,Spring使用这三个包实现AOP

<beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:context="http://www.springframework.org/schema/context"     xmlns:aop="http://www.springframework.org/schema/aop"     xsi:schemaLocation="http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd         http://www.springframework.org/schema/context         http://www.springframework.org/schema/context/spring-context-3.0.xsd            http://www.springframework.org/schema/aop         http://www.springframework.org/schema/aop/spring-aop.xsd">   <!--1, 打开Spring的annotation -->   <context:annotation-config/>   <!-- 2, 设定Spring去那些包中找annotation -->   <context:component-scan base-package="com.yangw.spring" />   <aop:config>       <!-- 定义切面 -->       <aop:aspect id="myLogAspect" ref="logAspect">           <!-- 在哪些位置加入相应的Aspect-->           <aop:pointcut id="logPointCut" expression="execution(* com.yangw.spring.dao.*.add*(..))||                   execution(* com.yangw.spring.dao.*.delete*(..))||                   execution(* com.yangw.spring.dao.*.update*(..))" />           <!-- 定义通知 -->           <aop:before method="logStart" pointcut-ref="logPointCut"/>           <aop:after method="logEnd" pointcut-ref="logPointCut"/>           <aop:around method="logAround" pointcut-ref="logPointCut"/>       </aop:aspect>   </aop:config></beans>
package com.yangw.spring.proxy;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.springframework.stereotype.Component;@Component("logAspect") //交给Spring管理public class LogAspect1 {    public void logStart(JoinPoint jp){        System.out.println(jp.getTarget()); //得到执行的类        System.out.println(jp.getSignature().getName()); //得到执行的方法名        Logger.info("log start.");    }    public void logEnd(JoinPoint jp){        System.out.println(jp.getTarget()); //得到执行的类        System.out.println(jp.getSignature().getName()); //得到执行的方法名        Logger.info("log end.");    }    public void logAround(ProceedingJoinPoint pjp) throws Throwable{        Logger.info("log around start");        pjp.proceed(); //让程序往下执行        Logger.info("log around end.");    }}

测试和结果与前面的基于annotation的一模一样,不在赘述!

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,494
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,295