Spring基本知识

重要的Spring模块

  1. Spring Core:核心模块,主要提供IOC依赖注入功能
  2. Spring AOP:面向切面的编程实现
  3. Spring JDBC : 连接数据库
  4. Spring Web:创建Web程序
  5. Spring Test:Junit和TestNG的测试功能
  6. Spring WebSocket:很方便实现即使聊天的组件

@RestController和@Controller

  1. 前者:放到一个类上面,代表此类的所有接口返回的是JSON类型的数据。
  2. 后者:返回一个页面,如果想要某个接口返回JSON数据,则需在接口加上@ResponseBody

Spring IOC 和 AOP

IOC,控制反转,将原本在程序中手动创建对象的控制权,交由Spring框架来管理。spring实现的方式是IOC容器,就是一个map,存放各种对象。
具体实现是依赖注入:将底层类作为参数传递给上层类,实现上层类对底层类的控制。有通过构造方法传递的,还有通过Set传递和接口传递。

控制反转容器:就是依赖注入需要注入上层类依赖的底层类,这些底层类的初始化就是容器做的。
https://www.zhihu.com/question/23277575/answer/169698662

AOP,面向切面编程,将与业务无关的逻辑封装起来,减少系统代码重复。
基于动态代理,代理的对象实现了某个接口,则使用JDK的JDKProxy。否则使用Cglib,生成一个被代理对象的子类

//JDKproxy
package com.example.demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JDKProxyDemo {
    static interface Inter{
        void oneMethod();
    }
    //被代理类
    static class interImpl implements  Inter {

        @Override
        public void oneMethod() {
            System.out.println("被代理类的方法执行");
        }

    }
    //生成代理类的处理类
    static class JdkProxy implements InvocationHandler {
        //被代理类对象
        private Object object;
        //将被代理对象和处理类绑定
        public Object bind(Object o) {
            this.object = o;
            return Proxy.newProxyInstance(object.getClass().getClassLoader(),
                    object.getClass().getInterfaces(),this);
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("代理类对方法的增强");
            Object invoke = method.invoke(object, args);
            return invoke;
        }
    }

    public static void main(String[] args) {
        //生成一个代理类
        JdkProxy jdkProxy = new JdkProxy();
        Inter inter = (Inter) jdkProxy.bind(new interImpl());
        //动态生成代理类对象
        inter.oneMethod();
    }
}

//Cglilb
package com.example.demo;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibDemo {
    static class SayHello {
        public void sayHello() {
            System.out.println("say hello");
        }
    }
    static class CglibDemoE implements MethodInterceptor {

        public Object getProxy(Class cls) {
            //cglib增强类对象
            Enhancer enhancer = new Enhancer();
            //设置增强类型
            enhancer.setSuperclass(cls);
            //定义代理逻辑对象为当前对象
            enhancer.setCallback(this);
            return enhancer.create();
        }

        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("增强了");
            Object o1 = methodProxy.invokeSuper(o, objects);
            return o1;
        }
    }

    public static void main(String[] args) {
        CglibDemoE cglibDemoE = new CglibDemoE();
        SayHello proxy = (SayHello) cglibDemoE.getProxy(SayHello.class);
        proxy.sayHello();
    }
}

JDK 动态代理使用的是反射技术,被代理的类要实现方法接口。
CGLIB 动态代理使用的是字节码增强技术,被代理的类不用实现方法接口

Spring Bean

  1. Spring Bean的作用域
    Singleton:唯一bean实例
    prototype: 每次请求都会创建一个新的bean
    request:一次请求期间一个bean
    session:一个会话期间一个bean

  2. Spring 中的单例 bean 的线程安全问题了解吗?
    单例bean,是所有线程都使用这一个bean,存在多线程操作安全问题。但是spring默认是单例bean,是因为大多数的bean是无状态的,就是只是controller,dao,service层使用,只操作方法。
    无状态就是不会存储数据。且无状态就是只有方法,而方法对应着jvm的虚拟机栈。

    可以使用ThreadLocal来封装。

  3. @Component 和 @Bean 的区别是什么?
    作用对象不同:前者作用与类,而后者作用与方法。
    @Component通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用 @ComponentScan 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。@Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean,@Bean告诉了Spring这是某个类的示例,当我需要用它的时候还给我。

  4. 将一个类声明为Spring的 bean 的注解有哪些?
    @Component :通用的注解,可标注任意类为 Spring 组件。如果一个Bean不知道属于哪个层,可以使用@Component 注解标注。

    @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作

    @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao层。

    @Controller : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面

Spring MVC工作原理

  1. 客户端发送请求到DispacherServlet,
  2. 前端控制器,根据请求调用HanlerMapping,解析出请求对应的handler,也就是对应的Controller控制器。
  3. 之后就由HandlerAdapter适配器,执行具体的流程。
  4. 处理完毕就返回一个modelAndView对象,Model是数据,View是逻辑上的页面。
  5. 视图解析器通过View找到真正的页面view
  6. 前端控制器将数据渲染到视图,填充数据到request,响应数据。

spring事务

声明式事务,基于xml或者注解

  1. 事务隔离级别?
    TransactionDefinition定义了5个
    默认隔离级别,就是和数据库隔离级别保持一致,myslq就是可重复读,oracle则是读已提交

    其余就是读未提交,读已提交,可重复读、序列化

  2. 事务传播行为?
    支持当前事务:
    当前有事务,则加入当前事务、当前没有则新创建一个
    当前有事务,加入,没有则已非事务运行。
    当前有事务,加入,否则抛异常

    不支持当前事务
    创建一个新的事务,当前有则挂起当前的
    以非事务运行,当前有则挂起当前
    以非事务运行,当前有则抛异常

  3. @Transactional(rollbackFor = Exception.class)注解了解吗?
    如果不加则只会有运行时异常抛出时才会回滚数据,加了就是Exception都会回滚

上一篇:32_使用BeanUtils工具包操作JavaBean


下一篇:00 - Vue3 UI Framework - 阅读辅助列表