• Spring两个特点


    Spring最重要的两个特点:1.依赖注入;2.切面编程,aop编程。

    1.依赖注入是什么?为什么要有依赖注入?

      依赖注入就是我们要使用某个对象,不是我们自己在程序里面通过new生成对象,而是通过Spring容器加载配置文件ApplicationContext.xml等生成对象;Spring容器帮助我们管理对象的创建,调用与回收;

     

     对于依赖的对象要自己在构造函数里面生成 

      this.quest = new RescueDamselQuest(); 

    这样使程序紧耦合,RescueDamselKnight只能处理RescueDamselQuest的任务,不能处理其他Quest实例 ,这样不利于组件重组,代码利用率比较低且不利于维护;

      接口被传入进来,具体传进来的是什么根据Spring容器决定(Quest可以有很多实现);使用的是哪个具体的Quest,BravaKnight并不知道,只有配置文件才晓得。Spring项目里面也是通过注解@Autowired Interface,生成实现该接口的一个实例,而具体由谁实习该接口,配置文件里面会定义。

    2. 为什么需要AOP编程?

      aop,面向切面编程,这个是对oop(面向对象编程)的补充;oop是用来完成核心业务逻辑,但是有一些公共性的行为,比如日志,权限验证等可能在很多对象里面里面都有用到,我们不能在这些对象的程序里面把日志和权限验证的代码都写一遍,这样太繁琐了而且对象之间的耦合性很高。所以我们把这些公共性的行为抽象封装起来,在配置文件里面决定在哪些地方使用这些行为。

      2.1动态代理实现aop编程

      接口IHello 

    public interface IHello{
        public void sayHi(String str);
    }

      实现IHello的类

    public class Hello implements IHello {
        public void sayHi(String str){
            System.out.println(str);
        }
    }

      我们想在方法sayHi()的前后添加一些操作,一个方法就是新建一个对象HelloCon。

    public class HelloCon implements IHello{
        private IHello hello;
        public HelloCon(IHello hello){
            this.hello = hello;
        }
        public void sayHi(String str){
            //操作1
            hello.sayHi(str);
            //操作2;
        }
    }

    另一个方法是我们使用代理模式访问Hello对象,与该代理对象绑定有一个InvocationHandler接口,我们重写该接口,操作1,操作2放在invoke()方法里面完成; 实现代理主要分为两部分:1.生成代理对象;2.重写InvocationHandler的invoke()方法。

    public class HelloHander implements InvocationHandler{
        public IHello hello;
        public HelloHander(IHello hello){
            this.hello = hello;
        }
         
        public Object getProxyObject(){
            return Proxy.newProxyInstance(
            this.getClass().getClassLoader(),IHello.class,this);
        }
        //proxy:与该Handler绑定的代理对象;
        //method:使用反射来实现代理对象对真实对象方法的调用
        //args:方法的形参
    public Object invoke(Object proxy, Method method, Object[] args) {
        //操作1
        method.invoke(hello,args);
        //操作2
        return null;
    }
    }
    /*
           loader:用来定义代理类的类装载器
           interfaces:代理类实现的接口
           h:实际处理的内容放在h里面
    
    */
    public static Object newProxyInstance(ClassLoader loader,
                                              Class<?>[] interfaces,
                                              InvocationHandler h)
            throws IllegalArgumentException{
            
                //将代理类将要实现的接口的字节码复制到intfs中
                  final Class<?>[] intfs = interfaces.clone();
                  
                 //如果这个代理类已经存在(该代理类由loader定义,并且实现了给定的接口),直接复制缓存返回即可,如果不存在,通过ProxyClassFactory创建新的代理类
                   Class<?> cl = getProxyClass0(loader, intfs);
     // 得到构造函数;constructorParams的构造函数是 //constructorParams(InvocationHandler.class)
                final Constructor<?> cons =   cl.getConstructor(constructorParams);
    //构造函数生成新的代理对象,传入的参数是代理对象要关联的invocationhandler
                return cons.newInstance(new Object[]{h});
            }
  • 相关阅读:
    Codeforces Round #647 (Div. 2) A
    Acwing 1129. 热浪 解题报告
    二分 + 三分模板
    可持久化线段树(主席树)模板
    《架构之美》-----阅读笔记四
    《架构之美》-----阅读笔记三
    《架构之美》-----阅读笔记二
    《架构之美》-----阅读笔记一
    《软件需求》------阅读笔记三
    《软件需求》------阅读笔记二
  • 原文地址:https://www.cnblogs.com/zhihuayun/p/7211269.html
Copyright © 2020-2023  润新知