zoukankan      html  css  js  c++  java
  • spring基本原理

    spring 的2个核心技术:

    ioc/di:控制反转/依赖注入

      所谓IoC(控制反转),对于spring框架来说,就是由spring来负责控制对象的生命周期对象间的关系

      IoC的一个重点(DI 依赖注入)是在系统运行中,动态的向某个对象提供它所需要的其他对象(因此又叫DI)。如对象A定义一个引用B(对象),至于这个B对象怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个B对象,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖B才能正常运行,而这个B是由spring注入到A中的,依赖注入的名字就这么来的。DI原理:Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

      没有spring时:在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。

      有spring时:有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转

    aop:面向切面:

      AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善

      AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。

      AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常伴随在核心关注点前后使用,而各处都基本相似。比如权限认证、日志、事务处理。

      AOP技术,利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。 Spring采用动态代理织入,而AspectJ采用编译器织入和类装载期织入。

        Spring AOP使用了两种动态代理机制:一种是基于JDK的动态代理,一种是基于CGLib的动态代理。JDK1.3以后,java提供了动态代理技术,允许开发者在运行期间动态的创建接口的代理实例,JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的结束拦截所有父类方法的调用,并顺势织入横切逻辑。

      基于JDK的动态代理      

    //创建代理类 (1)实现InvocationHandler接口
    class MyProxy implements InvocationHandler{
    //(2)创建一个Object引用 接受被代理者
    Object obj;
    /*(3)创建一个方法 Proxy.newProxyInstance(Foo.class.getClassLoader(),
    new Class[] { Foo.class },
    handler);
    此方法的作用是让this 拥有被代理者obj所具有的所有(接口中)方法
    */
    public Object newProxyInstance(Object obj){
    //让代理者和被代理者关联
    this.obj=obj;
    return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
    obj.getClass().getInterfaces(),
    this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    String methodName=method.getName();
    Object result=null;
    if(methodName.equals("add")){
    System.out.println("我是add方法只向前加的内容————————————");
    result=method.invoke(obj, args);
    System.out.println("我是add方法执行后加的内容————————————");
    }else if(methodName.equals("nihao")){
    System.out.println("我是nihao方法只向前加的内容++++++—");
    result=method.invoke(obj, args);
    System.out.println("我是nihao方法执行后加的内容+++++———");
    }else{
    System.out.println("我是hehe方法只向前加的内容");
    result=method.invoke(obj, args);
    System.out.println("我是hehe方法执行后加的内容");
    }
    System.out.println();
    return result;
    }

    public static void main(String[] args) {
    //创建一被代理者
    Demo3 d3=new Demo3();
    //创建一个代理者
    MyProxy mp=new MyProxy();
    //让代理者和被代理者关联 产生一个inter2类型的对象
    Inter2 i2=(Inter2)mp.newProxyInstance(d3);
    //执行i2的方法
    i2.hehe();

        CGLib的动态代理

    //代理类
    public class CglibProxy implements MethodInterceptor { // private static CglibProxy proxy = new CglibProxy(); private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz) { enhancer.setSuperclass(clazz);// 设置需要创建子类的类 enhancer.setCallback(this); return enhancer.create();// 通过字节码技术动态创建子类实例 } @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { PerformanceMonitor.begin(arg0.getClass().getName() + "." + arg1.getName()); Object result = arg3.invokeSuper(arg0, arg2); PerformanceMonitor.end(); return result; } }
    //目标类
    public class UserServiceImpl{
    
        public void removeUser(int userId) {
            System.out.println("模拟删除用户:" + userId);
        }
    
        public void addUser(int userId) {
            // TODO Auto-generated method stub
        }
    
        public static void main(String[] args) {
            CglibProxy proxy = new CglibProxy();//代理者
            UserServiceImpl userService =(UserServiceImpl)proxy.getProxy(UserServiceImpl.class);//生成目标类的代理类
            userService.removeUser(7);
        }
    }
  • 相关阅读:
    Linux的命令技巧
    MAC地址表、ARP缓存表以及路由表
    边缘触发(Edge Trigger)和条件触发(Level Trigger)
    vue-router跳转页面
    正则表达式(简单易懂篇)
    Markdown快速使用指南
    WEB前端资源集(二)
    WEB前端资源集(一)
    js判断移动端与pc端
    js原声快速实现选项卡
  • 原文地址:https://www.cnblogs.com/qianfang123-java/p/spring_01.html
Copyright © 2011-2022 走看看