zoukankan      html  css  js  c++  java
  • spring02

    1、在spring容器中的一个bean的整个生命周期
    1、启动spring容器
    2、bean实例化
    3、装配属性
    4、BeanNameAware:setBeanName
    5、BeanFactoryAware:setBeanFactory
    6、ApplicationContextAware:setApplicationContext
    7、。。。。。。
    8、调用init方法
    9、后处理bean:BeanPostProcessor:改变一个bean的行为
    10、从spring容器中把一个bean提取出来,调用方法
    11、销毁

    2、springAOP:面向切面编程
    1、应用场景
    1、应用场景1
    Transaction tx = session.beginTransaction();
    session.save/update/delete/query
    tx.commit();

    目标:
    程序员只写session.save/update/.....
    事务谁写?
    2、应用场景2
    1、开启日志
    2、开启安全性的框架
    3、检查有没有权限
    4、如果有权限,则查看工资
    如果没有权限,则不能查看工资

    showSalary(){
    查看工资
    }

    logging(){
    //写日志
    }

    security(){
    //安全性框架
    }

    access(){
    //权限检查
    }


    最后会形成一个方法:(该方法是动态形成的):
    把上面所有的方法结合在一起了
    2、aop的原理:
    动态代理模式
    jdk动态代理
    目标接口
    目标类
    拦截器
    代理类实现了目标接口
    cglib动态代理
    目标类
    拦截器
    代理类是目标类的子类
    3、动态代理模式确实可以解决上面的问题,可以把下面的场景全部的分开来写
    1、开启日志
    2、开启安全性的框架
    3、检查有没有权限
    4、如果有权限,则查看工资
    但是实际的业务系统是比较复杂的,在ProxyFactoryBean中,生成代理对象的方法中需要做很多判断性的工作
    而且这些工作并不好做,所以动态代理模式是AOP的理论基础,但是并不能直接应用于企业开发

    4、aop的概念
    1、目标类
    2、切面:除了目标类以外,其他的都是切面,是一个类
    事务
    日志
    安全性框架
    权限
    3、通知
    切面中的方法就称为通知
    public class Transaction {//切面
    public void beginTransaction(){//通知
    System.out.println("begin transaction");
    }

    public void commit(){//通知
    System.out.println("commit");
    }
    }
    4、连接点
    客户端调用哪个方法,哪个方法就是连接点
    @Test
    public void testSave(){
    /**
    * 1、创建目标对象
    * 2、创建事务
    */
    Object target = new PersonDaoImpl();
    Transaction transaction = new Transaction();
    PersonDao personDao = (PersonDao)ProxyFactoryBean.getInstance(target, transaction);
    personDao.savePerson();//连接点
    }
    5、切入点:是一个条件
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    //if语句就是切入点
    if(method.getName().equals("")||method.getName().equals()){
    /**
    * 1、启动事务
    */
    transaction.beginTransaction();
    /**
    * 2、调用目标方法
    */
    method.invoke(target, args);
    /**
    * 3、提交事务
    */
    transaction.commit();

    }else{
    /**
    * 2、调用目标方法
    */
    method.invoke(target, args);
    }
    return null;//返回的是方法的返回值
    }
    6、织入
    形成代理对象方法体的过程
    5、aop存在的意义
    在做一件事情的过程中,这个事情可以分为目标类和很多切面,
    而目标类和很多切面是完全松耦合的,这样的方式有利于软件开发
    当形成代理对象的方法体的过程就把目标方法和通知结合在一起了

    6、spring的aop
    1、实现hibernate中的事务的重用
    2、各种通知
    1、前置通知
    1、在spring配置文件中的配置
    <aop:before method="beginTransaction" pointcut-ref="perform"/>
    2、该方法可以没有参数,也可以有参数,参数为JoinPoint,该参数为连接点
    客户端调用哪个方法,哪个方法就是连接点
    3、从连接点中可以获取的信息有
    //连接点的参数列表
    System.out.println(joinPoint.getArgs().length);
    //得到目标对象
    System.out.println(joinPoint.getTarget());
    //得到方法的名称
    System.out.println(joinPoint.getSignature().getName());
    2、后置通知
    1、后置通知的参数除了有JoinPoint以外,还可以有一个参数,该参数可以接收目标方法的返回值
    <aop:after-returning method="commit" returning="val"/>

    /**
    * 后置通知
    */
    public void commit(JoinPoint joinPoint,Object val){
    System.out.println("commit");
    System.out.println(val);
    }
    2、后置通知在目标方法执行之后执行
    3、当目标方法遇到异常以后,后置通知将不再执行
    3、异常通知
    1、获取到目标方法抛出的异常信息
    <aop:after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"/>

    /**
    * 异常通知
    */
    public void throwingMethod(JoinPoint joinPoint,Throwable ex) throws Throwable{
    System.out.println(ex.getMessage());
    }
    2、该异常处理是完全独立于系统之外的处理方式,该异常处理和action,service,dao层都没有关系
    和业务逻辑也没有关系,完全独立的
    4、最终通知
    无论目标方法是否有异常,都将执行,可以将资源的释放工作放在里面
    5、环绕通知
    /**
    * 环绕通知
    * JoinPoint
    * ProceedingJoinPoint
    */
    public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable{
    System.out.println("aaaa");
    joinPoint.proceed();//用来执行目标方法的
    }
    1、环绕通知可以控制目标方法的执行
    2、环绕通知也能得到JoinPoint里面的信息
    7、各种例子
    1、把action、service、dao层的类和接口放入到spring容器中
    利用springAOP的异常通知处理异常

    注意事项:
    目标类是谁?
    切面是谁?应该用哪个通知
    2、创建service层和dao层,计算连接点的执行时间?
    3、创建service层和dao层,权限处理的例子

    public class PersonService{
    private PersonDao personDao;
    //当前的用户只有拥有了"query person"权限才能访问queryPerson方法
    如果没有这个权限,是没有办法访问该方法的
    @PrivilegeInfo(name="query person")
    public void queryPerson(){

    }
    }
    Privilege:
    name
    List<Privilege> privileges;
    在客户端可以把用户拥有的权限放入到privileges中
    4、利用springaop处理缓存

    public class PersonDao{
    @Cacheable(name="put")
    public void savePerson(Person person){
    //把person对象放入到数据库中
    }

    @Cacheable(name="get")
    public void queryPerson(Long pid){
    //从数据库中提取person对象
    }
    }

    当检查到连接点上有注解@Cacheable,并且name的属性的值为"put"的时候
    做两件事情:
    1、把person放入到数据库中
    2、把person放入到缓存中Map<Long,Person>
    当检查到连接点上有注解@Cacheable,并且name的属性的值为"get"的时候
    要做的事情:
    先检查缓存中没有该值,如果有,则从缓存中把值提取出来
    如果没有,则从数据库中提取出来
    5、 打印出:xxxxx类的xxxxx方法在xxxxxx时间内被调用了多少次
    只计算service层就可以了
    8、理解

    1、切面肯定是一个系统级别的重用的和业务逻辑没有关系的类
    2、利用aop使得目标类和各个切面完全松耦合,这样设计的系统架构更好,更有利于团队开发,代码复用

  • 相关阅读:
    手动卸载Office2010
    css盒子模型和定位
    [转]Mysql 存储过程和函数区别
    (转载)今天面试两个人的感受
    配置apache和php mysql的一些问题
    css position[转
    drools7 (四、FactHandle 介绍)
    drools7 (三、kmodule 介绍)
    drools7 (二、agenda-group 的使用)
    drools7 (一、最简单的例子)
  • 原文地址:https://www.cnblogs.com/lixiaochao/p/5645081.html
Copyright © 2011-2022 走看看