动态代理:

    目的:在不改变源代码的情况下,对方法进行增强!
    
    动态代理又分为两种:
    1.第一个就是基于接口的动态代理,他是由jdk提供的
    2.基于子类的动态代理:cglib提供的:要想使用基于子类的动态代理:就必须得导入cglib的jar包
    
    特性:被代理对象的任意方法
    

Spring_aop:总结
aop(Aspect Oriented Programming) :面向切面编程

切面:相对于业务主线的额外的功能模块
在不改变程序源代码的情况下对方法进行增强

aop的底层原理就是动态代理
    aop的底层他会自动的根据代码,选择是使用基于还是使用子类的动态代理!
    
    使用aop进行编程有啥好处呢?
        1.简化业务代码
        2.维护简单
        
        Aop相关术语
        Joinpoint(连接点):执行的方法
        pointcut(切入点):被增强的方法
        Advice(通知/增强):就是额外的功能模块
            前置通知
            后置通知
            异常通知
            最终通知
            环绕通知
            Aspect(切面):
                对那个方法进行怎样的增强
        学习Aop重点关注的事情是啥呢?
        1.重点关注的是一个一个的额外的功能模块
        2.aop的配置
第三 spring Aop的开发流程
            定义一个切面类
            普通的Java类,在这个类中通过一个一个的方法对目标对象进行增强
            
            2.配置Aop
                在xml里面配置文件中aop
                i.将切面类交给spring管理
                
                ii.声明Aop配置
                <aop:config>
                iii.定义切入点
                aop:pointcut
                iiii.定义通知类型
                <aop:aspect ref = "切面类的引用">
                    前置通知
                    <aop:before method="切面类的方法名" pointcut-ref="切入点表达式是引用"/>
                    后置通知<aop:afterRunturning method="切面类的方法名" pointcut-ref="切入点表达式是引用"/>
                    异常通知<aop:after-throwing method="切面类的方法名" pointcut-ref="切入点表达式是引用"/>
                    最终通知<aop:after method="切面类的方法名" pointcut-ref="切入点表达式是引用"/>
                    注意:异常通知只有出现了异常了 才会有通知
                </aop:aspect>
                基于注解的Aop配置(结合xml)
            1.将切面类交给spring管理
            2.使用注解的形式代替xml中的aop的配置
            3.使用注解配置spring的ioc或者aop的时候都需要开启对注解的支持!
            
            注意:使用注解配置Aop和xml配置Aop在后置通知的时候,有一些差别!
            注解的配置:是最后执行后置通知!
            
            纯注解配置Aop
            1.声明配置类
            2.开启对ioc的支持
            3.开启对aop注解的支持
            @EnableAspectJAutoProxy
            
开发步骤以及代码的解释
        <!-- 将切面类交给spring管理 -->
        <bean id="logger" class="cn.itcast.utils.Logger"></bean>
        
        <!-- 声明AOP配置:需要使用aop的命名空间(必须导入aop的约束)
        aop:config : 声明aop配置
     -->
    <aop:config>
    
    <!-- 定义切入点:定义被增强的方法
            expression : execution(类的修饰符 返回值 包名.包名...类名.方法名(参数列表))
            1.类的修饰符可以省略 :返回值 包名.包名...类名.方法名(参数列表)
            2.返回值可以使用*号代替:标识任意返回值都可以
            3.包名可以使用*号代替,一个包需要一个*
            4.包名..代表此包   以及   此包的任意子包
            5.类名可以使用*代替,代表任意类
            6.方法名可以使用*代理,代表任意方法
            7.参数类别可以使用..代表任意参数
            
            **** 此写法 * *..*.*(..) 不推荐
            
         -->
        <aop:pointcut expression="execution(* cn.itcast.service.impl..*.*(..))" id="pt"/>
        
        
        
        <!-- 配置切面
                aop:aspect
                    ref:被spring管理的切面类的引用
        -->
        <aop:aspect ref="logger">
        
        
            <!-- 定义通知的类型
                aop:before  定义前置通知
                    method:切面类中定义的方法名
                    pointcut-ref:切入点表达式是引用
            -->
            <aop:before method="before" pointcut-ref="pt"/>
            
            这是xml里面的配置
            
注解配合xml使用代码以及解释
    <!-- 开启对spring ioc的支持 -->
    <context:component-scan base-package="cn.itcast"></context:component-scan>
    
    <!-- 开启对aop注解的支持 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
    
    /*
 * 切面类:
 *         对目标对象进行日志部分的增强是通过此类中的方法来实现
 * 在切面类上
 *         定义切面类
 * 在切面方法上
 *         使用注解的形式定义通知类型
 */
@Component("logger")
@Aspect
public class Logger {//这是配置到类上的

/**
     * 抽取切入点表达式
     *         @Pointcut:定义切入点表达式
     *             这个注解需要配置到方法上,这个方法是一个空的方法
     *             应用这个切入点表达式的时候,只需要引入方法名就可以了
     *             但是需要  方法名()   需要加括号
     */
    @Pointcut(value="execution(* cn.itcast.service.impl..*.*(..))")//注意:类名前面那两个点改成一个点也是可以的
    @Pointcut(value="execution(* cn.itcast.service.impl.*.add*(..))")//这是指定对那个方法进行增强
    public void pt() {//定义一个通用的,这样前置通知,后置通知等等用的时候只需要引用这个方法名就行了
        
    }
    
    /**
     * 定义前置通知
     *     @Before :
     *         value : 可以是一个切入点表达式,也可以是一个切入点表达式的引用
     *             切入点表达式    
     */
    @Before("pt()")
    public void before() {
        System.out.println("进入方法之前打印日志");
    }
    
            
    *这是注解配置xml的方法

纯注解的配置方式

/*
 * 切面类:
 *         对目标对象进行日志部分的增强是通过此类中的方法来实现
 * 在切面类上
 *         定义切面类
 * 在切面方法上
 *         使用注解的形式定义通知类型
 */
@Component("logger")
@Aspect
public class Logger {
    
    /**
     * 抽取切入点表达式
     *         @Pointcut:定义切入点表达式
     *             这个注解需要配置到方法上,这个方法是一个空的方法
     *             应用这个切入点表达式的时候,只需要引入方法名就可以了
     *             但是需要  方法名()   需要加括号
     */
    @Pointcut(value="execution(* cn.itcast.service.impl..*.*(..))")
    public void pt() {
        
    }
    
    /**
     * 定义前置通知
     *     @Before :
     *         value : 可以是一个切入点表达式,也可以是一个切入点表达式的引用
     *             切入点表达式    
     */
    @Before("pt()")
    public void before() {
        System.out.println("进入方法之前打印日志");
    }
    
    
    @AfterReturning("pt()")
    public void afterReturning() {
        System.out.println("执行目标方法得到返回值后打印日志");
    }
    
    @AfterThrowing("pt()")
    public void afterThrowing() {
        System.out.println("抛出异常打印日志");
    }
    
    @After("pt()")
    public void after() {
        System.out.println("在最终代码块中打印日志");
    }
    
    //5.定义环绕通知
    /**
     * 环绕通知是spring提供的一种
     *     让程序员手动指定要执行的增强方法的一种手段,
     * 在此方法中可以根据需求自定义以上4中通知类型
     *     在环绕通知中,需要手动去调用被增强的方法
     *     借助spring提供的一个对象ProceedingJoinPoint
     *             此对象中有一个方法,可以调用被增强的方法
     *         pjp.proceed();执行被增强的的方法
     *             eg:动态代理中的,method.invoke();
     *
     * @throws Throwable
     */
    @Around("execution(* cn.itcast.service.impl..*.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("前置通知");
        Object obj = null;
        try{
            obj = pjp.proceed();
            System.out.println("后置通知");
        }catch(Exception e){
            System.out.println("异常通知");
            e.printStackTrace();
        }finally{
            System.out.println("最终通知");
        }
        return obj;
    }
}

/spring的配置类
//在配置类中替换xml配置文件中的剩余配置项

/**
 * 1。声明配置类
 * 2。开启对ioc的支持
 * 3。开启对AOP注解的支持
 *         @EnableAspectJAutoProxy
 *
 */
@Configuration
@ComponentScan(basePackages="cn.itcast")
@EnableAspectJAutoProxy
public class Config {

}

    public class Client {

    public static void main(String[] args) {
        //测试ioc的配置
        //ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
        
        CustomerService customerService = (CustomerService)ac.getBean("customerService");
        customerService.updateCustomer();
    }
}
        这是纯注解的方式
        
        Aop事物案例
        
        @Component("logger")
@Aspect
public class Logger {
    
    @Pointcut(value="execution(* cn.crm.service.impl..*.*(..))")
    public void pt(){
        
    }
    
    @Around(value="pt()")
    public Object tx(ProceedingJoinPoint pjp) throws Throwable{
        Session session = null;
        Transaction tx = null;
        
        Object obj = null;
        
        try {
            session = HibernateUtils.getCurrentSession();
            tx = session.beginTransaction();
            
            obj = pjp.proceed();
            
            tx.commit();
            
        } catch (Exception e) {
            System.out.println("出现异常了");
            tx.rollback();
            
        }finally {
            
            System.out.println("最终执行的代码");
            
        }
        
        return obj;
        
    }
    

}

    public class Client{
        public static void main(String[] args) {
        
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        
        CustomerService customerService = (CustomerService)ac.getBean("customerService");
        
        
        Customer customer = new Customer();
        
        customer.setCustName("hello");
        
        customerService.addCustomer(customer);
    }
        
    }

        xml配置:
         <context:component-scan base-package="cn.crm"></context:component-scan>
        
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
        
        
        
        这是一个小小的Aop的事物案例,当然Spring也提供了事物的支持,但是今天只做了个Aop的事物,希望对大家有帮助

Spring_Aop的xml和注解的使用的更多相关文章

  1. 关于Mybatis中Mapper是使用XML还是注解的一些思考

    XML 据说可以灵活的进行注解,但是修改以后还是要重新发布程序.当然,你可以说,在Tomcat中改了,然后热加载了,不就可以了.可是一般情况下都是几台,十几台服务器.都是用发布系统,持续集成的方式部署 ...

  2. 【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比

    [原文]https://www.toutiao.com/i6594205115605844493/ Spring学习Bean配置的三种方式(XML.注解.Java类)介绍与对比 本文将详细介绍Spri ...

  3. 1-spring xml 和 注解 解析过程

    spring mvc 入口 DispatcherServlet,类关系图如下所示 DispatcherServlet 就是一个 Servlet,那Servlet 的初始化方法 init()在哪里,通过 ...

  4. MyBatis 使用简单的 XML或注解用于配置和原始映射

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .My ...

  5. Mybatis之XML、注解

    前言 上篇简单介绍了Mybatis的简单实用,本篇先对上次实验环境的一些内容进行优化,然后验证Mybatis的XML配置以及注解方式. 实验环境优化 数据库配置 在mybatis的配置文件中,引入数据 ...

  6. 使用spring框架时,使用xml还是注解

    1 xml的优缺点 1.1 优点 解耦合,方便维护.xml不入侵代码,方便代码阅读. 1.2 缺点 开发速度慢. 2 注解的优缺点 2.1 优点 能够加快开发速度,因为它将常用的主体逻辑隐藏在注解中了 ...

  7. day38 18-Spring的XML和注解的结合使用

    什么情况下使用XML,什么情况下使用注解?又有XML,又有注解,开发的时候使用哪种? XML:结构清晰,配置麻烦. 注解:简单, 它俩的结合点在属性注入上. 两种方式结合:一般使用XML注册Bean, ...

  8. 八 Spring的IOC的XML和注解的区别及其整合开发

    xml和注解的区别 xml和注解整合开发 注解:取消扫描配置开启注解配置 扫描:<context:component-scan base-package="" />  ...

  9. 二十 Spring的事务管理及其API&事务的传播行为,编程式&声明式(xml式&注解式,底层AOP),转账案例

    Spring提供两种事务方式:编程式和声明式(重点) 前者需要手写代码,后者通过配置实现. 事务的回顾: 事务:逻辑上的一组操作,组成这组事务的各个单元,要么全部成功,要么全部失败 事务的特性:ACI ...

随机推荐

  1. git log 中文乱码问题(浪费了一天)

    git log和gitcommit中文出现乱码,花了大半天的时间试了网上的各种方法,还是搞不定. 只好放大招. 卸载软件后重装,还没有进行任何配置,git config --list 发现有大量的配置 ...

  2. codeforces 630C - Lucky Numbers 递推思路

    630C - Lucky Numbers 题目大意: 给定数字位数,且这个数字只能由7和8组成,问有多少种组合的可能性 思路: 假设为1位,只有7和8:两位的时候,除了77,78,87,88之外还哇哦 ...

  3. PHP进程锁

    <?php /** * CacheLock 进程锁,主要用来进行cache失效时的单进程cache获取,防止过多的SQL请求穿透到数据库 * 用于解决PHP在并发时候的锁控制,通过文件/eacc ...

  4. Elasticsearch JAVA api搞定groupBy聚合

    本文给出如何使用Elasticsearch的Java API做类似SQL的group by聚合.为了简单起见,只给出一级groupby即group by field1(而不涉及到多级,例如group ...

  5. QT的radioButton组的使用

    在使用Qt的radioButton控件时,会产生一个疑问,如何让你选择的那个radio得到一个数据,进行判断,网上的一些资料有些不全,容易出错. 所以你得做件事,给每个radioButton进行赋初值 ...

  6. Web前端学习——HTML

    HTML其实还是蛮容易学习的,无非就是一些标签.格式的填写,大学的时候也做过网站设计,所以这里主要记录一些常用的HTML标签.属性以及书写方法等. 一.常见HTML格式 主要包含文件type,html ...

  7. Redis在Linux安装详细步骤

    一.准备环境: 1.VMware 2.CentOS 3.redis-3.0.4.tar.gz 4.下载地址 Http://redis.io/   英文版 Http://www.redis.cn/  中 ...

  8. c++邻接表存储图(无向),并用广度优先和深度优先遍历(实验)

    一开始我是用c写的,后面才发现广搜要用到队列,所以我就直接使用c++的STL队列来写, 因为不想再写多一个队列了.这次实验写了两个多钟,因为要边写边思考,太菜了哈哈. 主要参考<大话数据结构&g ...

  9. How to support comparators in our sort implementations?

    上图是普林斯顿算法课part1.Mergesort章节给出的参考代码,可以发现这个代码有三处警告.造成的隐患就是我们无法在类型检查时发现送入sort()函数的数组元素类型和Comparator的泛型不 ...

  10. LeetCode OJ 之 Ugly Number II (丑数-二)

    题目: Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose prime fact ...