Spring编程<四>

来源:互联网 发布:安卓手机数据恢复apk 编辑:程序博客网 时间:2024/06/17 15:18

Spring编程<四>

自动代理技术:

配置文件中的自动代理:
在配置文件中加:
使得每次使用bean时,他会自动给bean添加切面advisor;

<!-- 自动代理,自动找 Advisor-->    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>

也可以写我们自己的自动代理

/* * 自定义自动代理: *  2个知识点: *      1)获取项目中的全局容器:通过实现一个监听器  ApplicationContextAware监听器接口 *          ----该技术可以让一个普通类(非Web环境)获取到项目的全局bean容器 *      2)获取当前其他模块从bean容器中取出的bean,通过实现BeanPostProcessor监听器接口(拿到后,我来处理)*/public class MyAutoProxyCreator implements ApplicationContextAware,BeanPostProcessor{    private ApplicationContext ctx=null;    @Override    public void setApplicationContext(ApplicationContext ctx)            throws BeansException {        this.ctx=ctx;    }    ////////////下面2个函数是后处理Bean的///////////////    @Override//参数1为当前从容器中读出 bean    public Object postProcessAfterInitialization(Object bean, String str)            throws BeansException {        if (bean instanceof Person) {            //用户 当前将要获取的bean 转换成代理后的对象(bean),然后返回            ProxyFactoryBean factory = new ProxyFactoryBean();            factory.setTarget(bean);//原型            //到bean容器(ctx)中,遍历出所有advisor,添加到factory中,本来要获取Map,本例简化只拿一个            Advisor ad = ctx.getBean(Advisor.class);//会到bean中找该接口实现类创建的            factory.addAdvisors(ad);            return factory.getObject();        }else{            return bean;        }    }    @Override    public Object postProcessBeforeInitialization(Object bean, String str)            throws BeansException {        return bean;    }}

关于切点语言:

演示需要的Person类
这里写图片描述

/*     *切点语言:     *   1)框架 execution(切点语言表达式)     *   2)表达式格式:  返回类型   包名[子包名...].类名.方法名(参数类型列表)     *   3)"."  在包名与报名 或 包名与类名之间 或 类名与方法名 之间的间隔符     *   4)".." 在包路径位置代表的是 任意深 的目录,如果在参数类型列表中 代表的是 任意个数与类型的参数     *   5)"*"  是操作系统中的通配符 代表任意字符     */

演示:

//演示切点语言    @Test    public void t1(){        //代理工厂                ProxyFactoryBean factory = new ProxyFactoryBean();                //声明切点                AspectJExpressionPointcut cut =new AspectJExpressionPointcut();                //设置切点表达式--切点语言                //cut.setExpression("execution( void cn.hncu.v2.Person.*() )");拦Person中所有空参方法                //cut.setExpression("execution( void cn.hncu.v2.Person.*(String) )");拦所有返回类型为空,参数类型为String                //cut.setExpression("execution( void cn.hncu.v2.Person.*(*) )");//拦返回空,一个参数                //cut.setExpression("execution( * cn.hncu.v2.Person.*(*) )");//拦返回类型任意,一个参数                //cut.setExpression("execution( String cn.hncu.v2.Person.*(..) )");//拦返回类型String,任意参数                //返回类型为任意,cn.hncu下的任意子包,任意深度,son结尾,任意函数名,任意参数                cut.setExpression("execution( * cn.hncu..*son.*(..) )");                    //至少一个参数            //  cut.setExpression("execution( * cn.hncu..*son.*(*,..) )");                //通知                Advice advice= new MethodInterceptor() {                    @Override                    public Object invoke(MethodInvocation invocation) throws Throwable {                        System.out.println("...前...");                        Object res=invocation.proceed();                        System.out.println("...后...");                        return res;                    }                };                //切面=  切点 + 通知                Advisor advisor=new DefaultPointcutAdvisor(cut, advice);                //把切面加到代理工厂                factory.addAdvisor(advisor);                //从工厂取出的bean都是被代理过的                Person p = new Person();                factory.setTarget(p);                p=(Person) factory.getObject();                p.run();                p.hello();                p.fun("abc");                p.abc("abc123");                p.ok("ok", 8);    }

因为用到了自动代理和切点语言,所以还要导入包:

这里写图片描述