Spring编程<四>

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);
    }

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

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值