Spring框架

Spring框架

spring是一个Java企业级应用的开源开发框架。
1、轻量:一个轻量级框架,基本的只需要大约2M。
2、控制反转:通过控制反转实现松散耦合,对象们给出他们的依赖,而不是创建或查找依赖的对象。
3、面向切面(aop):可以将业务逻辑和系统服务分开。
4、容器:管理应用中对象的生命周期和配置。
5、mvc框架:是web的一个很好的替代品。
6、事务管理:有一个持续的事务管理接口,可以扩展到上至本地事务,下至全局事务。

核心框架

功能
  1. IoC容器:Spring的IoC容器是Spring的核心,它是一种用于管理对象的机制,负责将对象的创建、配置和组装等过程从应用程序中分离出来,提供了一种松耦合的设计方式。Spring的IoC容器提供了两种不同的实现方式,分别是基于XML文件的配置方式和基于注解的配置方式。

  2. AOP框架:Spring的AOP框架是一种基于代理的技术,用于实现横向切面的功能,可以将一些通用的业务逻辑和处理逻辑抽象成切面,并通过动态代理技术将切面织入到目标对象的方法中,从而实现代码复用和解耦。

  3. 数据访问框架:Spring提供了多种数据访问框架,如JDBC模板、ORM框架、事务管理等,支持各种不同的数据库和数据访问方式,可以大大简化数据访问的开发过程。

  4. Web框架:Spring提供了多种Web框架,如Spring MVC、WebFlux等,可以帮助开发人员快速构建Web应用程序,并提供了一套完整的MVC框架、视图解析器、数据绑定等功能。

  5. 消息队列框架:Spring提供了多种消息队列框架,如Spring AMQP、Spring Kafka等,可以帮助开发人员实现异步消息传递和处理。

  6. 安全框架:Spring提供了Spring Security框架,用于处理Web应用程序的安全问题,包括身份认证、授权管理、会话管理等。

模块
  1. Spring Core:Spring Core是Spring框架的核心模块,提供了IoC容器和DI(Dependency Injection)功能,它可以管理Java对象的生命周期,实现对象之间的依赖注入和控制反转,提供了面向接口的编程模型,是Spring框架的基础。

  2. Spring AOP:Spring AOP模块提供了AOP(Aspect Oriented Programming)框架,用于在应用程序中实现横向切面的功能,可以将一些通用的业务逻辑和处理逻辑抽象成切面,并通过动态代理技术将切面织入到目标对象的方法中,从而实现代码复用和解耦。

  3. Spring MVC:Spring MVC是Spring框架的Web框架,可以帮助开发人员快速构建Web应用程序,并提供了一套完整的MVC框架、视图解析器、数据绑定等功能。

  4. Spring Data:Spring Data模块提供了各种数据访问方式的支持,如JPA、Hibernate、MongoDB、Redis等,可以帮助开发人员快速构建数据访问层的代码。

  5. Spring Security:Spring Security模块提供了Web应用程序的安全功能,包括身份认证、授权管理、会话管理等,可以帮助开发人员实现Web应用程序的安全性保护。

  6. Spring Batch:Spring Batch模块提供了批处理功能,可以帮助开发人员快速实现大规模数据处理、批量任务调度等功能。

  7. Spring Integration:Spring Integration模块提供了集成其他系统的支持,如JMS、Web Services、Email、FTP等,可以帮助开发人员快速实现不同系统之间的数据传输和集成。

理解MVC

Spring MVC是Spring框架的一个模块,它是一个基于MVC(Model-View-Controller)架构的Web框架,用于开发Web应用程序。Spring MVC框架提供了一套完整的MVC框架、视图解析器、数据绑定等功能,可以帮助开发人员快速构建Web应用程序。

在Spring MVC中,请求会先由前端控制器(DispatcherServlet)接收,然后交给处理器映射器(HandlerMapping)进行处理器的映射,然后再由处理器适配器(HandlerAdapter)进行处理器的适配,最后交给处理器(Controller)进行处理。处理器处理完请求之后,将返回结果交给视图解析器(ViewResolver)进行视图的解析,最终返回给前端控制器,由前端控制器将视图展示给用户。

常用注解

@Autowired:用于自动装配Spring容器中的Bean,可以用于注入依赖的对象。

@Resource:用于自动装配Spring容器中的Bean,可以用于注入依赖的对象。

@Component:用于标注Spring组件,可以用于将类注册为Bean,并交给Spring容器管理。

@Service:用于标注服务层组件,通常用于注入DAO层的对象。

@Repository:用于标注DAO层组件,通常用于与数据库交互的对象。

@Controller:用于标注控制器组件,通常用于处理用户请求和响应。

@RequestMapping:用于映射请求URL和处理方法,可以用于指定请求的HTTP方法和请求参数等。

@ResponseBody:用于将方法的返回值转换成JSON或XML格式的数据,用于响应客户端请求。

@PathVariable:用于获取请求URL中的占位符参数,通常用于RESTful风格的API开发。

@RequestBody:用于获取请求体中的参数,通常用于处理POST请求中的JSON或XML数据。

@Value:用于获取配置文件中的属性值,可以用于注入依赖的属性。

Autowired和Resource注解的区别?

两者都是用作bean注入的

  1. @Autowired注解是Spring框架提供的注解,用于将一个Bean对象自动注入到另一个Bean对象中。它可以用于注入任何类型的Bean对象,包括基本类型、数组、集合、接口等等。Autowired注解在进行Bean装配时,默认使用byType的方式,即根据类型来匹配需要注入的Bean对象。如果有多个类型相同的Bean对象,则需要通过@Qualifier注解或者@Primary注解来进行区分。Autowired注解是J2EE规范的一部分,可以跨平台使用。

  2. @Resource注解是Java EE提供的注解,用于将一个Bean对象自动注入到另一个Bean对象中。与@Autowired注解不同的是,@Resource注解可以指定Bean对象的名称,也可以使用byType的方式进行注入。如果指定了名称,则会根据名称来查找需要注入的Bean对象,否则会使用byType的方式进行匹配。@Resource注解可以用于注入Java EE和Spring管理的Bean对象。

容器IOC

在IoC容器中,对象的创建和销毁都由容器来管理,对象之间的依赖关系也由容器来负责注入。开发人员只需要定义对象的实现类和依赖关系,然后交给容器来实现,从而实现程序的松耦合。

依赖注入DI

依赖注入是一个过程,在这个过程中,对象仅通过构造函数参数、工厂方法的参数或在对象实例被构造或从工厂方法返回后在对象实例上设置的属性来定义它们的依赖关系(即它们所使用的其他对象)。然后,容器在创建 Bean 时注入这些依赖项。这个过程从根本上讲是 Bean 本身的逆过程(因此称为控制的逆过程),通过使用类的直接构造或服务定位器模式来控制其依赖项的实例化或位置。

注入的方式
  1. 基于构造函数的依赖注入:基于构造函数的 DI 是由容器调用具有多个参数的构造函数来完成的,每个参数表示一个依赖项。调用带有特定参数的static工厂方法来构造 Bean 几乎是等效的,并且此讨论将参数处理为构造函数和基于 setter 的依赖注入工厂方法。
    下面的示例展示了一个只能通过构造函数注入进行依赖注入的类:
public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on a MovieFinder
    private final MovieFinder movieFinder;

    // a constructor so that the Spring container can inject a MovieFinder
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // business logic that actually uses the injected MovieFinder is omitted...
}
  1. 基于 setter 的依赖注入:在调用一个无参数构造函数或一个无参数static工厂方法来实例化你的 Bean 之后,容器调用 bean 上的 setter 方法来完成基于 setter 的 DI。
    示例:
public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on a MovieFinder
    private final MovieFinder movieFinder;

    // a constructor so that the Spring container can inject a MovieFinder
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // business logic that actually uses the injected MovieFinder is omitted...
}
循环依赖

循环依赖是指两个或多个Bean之间相互依赖,且依赖关系形成环路的情况。在Spring框架中,当出现循环依赖的情况时,通常会抛出BeanCurrentlyInCreationException异常,表示Bean正在创建中,无法完成依赖注入。

为了解决循环依赖问题,Spring框架采用了“提前暴露Bean”的策略,即将正在创建的Bean提前暴露给其他Bean,以避免循环依赖的问题。具体实现方式如下:
首先,Spring框架会创建BeanA,并将其加入到缓存中。
然后,当Spring框架创建BeanB时,发现需要依赖BeanA,但是BeanA还没有创建完成,因此Spring框架会将BeanA提前暴露出来,以供BeanB进行依赖注入。
接着,当Spring框架创建BeanA时,发现需要依赖BeanB,但是BeanB也还没有创建完成,因此Spring框架会将BeanB提前暴露出来,以供BeanA进行依赖注入。
最后,Spring框架完成了BeanA和BeanB的创建,并将它们加入到缓存中,以供其他Bean进行依赖注入。

切面AOP

AOP的核心是切面(Aspect),它定义了横切关注点的行为和逻辑,例如日志记录、事务管理、权限控制等。切面通常是一个包含多个通知(Advice)的模块,每个通知定义了在目标方法执行前、执行后或执行异常时需要执行的代码逻辑。
除了切面和通知,AOP还涉及到其他几个重要的概念:

  1. 连接点(Join Point):程序执行过程中可以插入切面代码的点,例如方法的调用、方法的返回、方法抛出异常等。
  2. 切点(Pointcut):用于选择连接点的表达式或规则,例如选择所有方法调用、选择指定包下的所有方法调用等。
  3. 引入(Introduction):用于向类添加新的方法和属性,从而为类添加新的行为。
  4. 织入(Weaving):将切面代码插入到目标对象中的过程,有三种实现方式:编译时织入、类加载时织入、运行时织入。
spring Aop和AspectJ AOP的区别

Spring AOP采用代理模式来实现AOP,即为目标对象动态地创建代理对象,并将切面代码织入到代理对象中,从而实现AOP的功能。Spring AOP只支持方法级别的连接点(Join Point),不支持类级别的连接点。

AspectJ AOP是一种基于编译时和运行时代码织入的AOP框架,它通过编译器或者类加载器将切面代码织入到目标对象中,从而实现AOP的功能。AspectJ AOP支持方法级别和类级别的连接点,还支持注解、枚举、泛型等特性。

关注点和横切关注的区别

关注点(Concern)是指在软件系统中引起开发人员关注的某个问题或特定的功能,例如安全、事务、日志、性能、缓存、验证等。

横切关注点(Cross-Cutting Concerns)是指与系统的多个模块或组件相关的关注点,它们通常跨越多个层次或模块,同时也与核心业务逻辑无关。例如日志记录、事务管理、权限控制、异常处理等。这些关注点往往会重复出现在不同的代码逻辑中,导致代码冗余和低效,同时也使得代码难以维护和扩展。

通知类型
  1. 前置通知(Before advice):在目标方法执行前执行的通知,可以用于在目标方法执行之前进行一些准备工作。

  2. 后置通知(After advice):在目标方法执行后执行的通知,可以用于在目标方法执行之后进行一些清理工作。

  3. 返回通知(After returning advice):在目标方法执行并返回结果后执行的通知,可以用于在目标方法执行之后对返回结果进行一些处理。

  4. 异常通知(After throwing advice):在目标方法抛出异常时执行的通知,可以用于在目标方法抛出异常之后进行一些处理。

  5. 环绕通知(Around advice):在目标方法执行前后都可以执行的通知,可以用于对目标方法的调用进行控制,例如在目标方法执行前进行参数校验,执行后进行结果处理等。

spring bean

bean的生命周期

在Spring容器中,Bean的生命周期包括以下几个阶段:

  1. 实例化(Instantiation):Spring容器使用Bean定义中指定的构造函数或工厂方法来创建Bean实例。

  2. 属性赋值(Populate properties):Spring容器将配置文件中指定的属性值或其他Bean引用注入到Bean实例中,这通常包括使用@Autowired、@Resource等注解进行依赖注入。

  3. 初始化(Initialization):Spring容器调用Bean实现了InitializingBean接口的afterPropertiesSet()方法,或者使用@Bean注解指定的initMethod方法来初始化Bean。

  4. 使用(In use):此时Bean已经可以使用了,它可以响应请求,执行业务逻辑等。

  5. 销毁(Destruction):当Spring容器关闭时,会调用Bean实现了DisposableBean接口的destroy()方法,或者使用@Bean注解指定的destroyMethod方法来销毁Bean。

在上述生命周期阶段中,实例化和销毁阶段由Spring容器管理,属性赋值、初始化和使用阶段则由开发人员自己控制。在实际应用中,开发人员通常使用@Bean注解或者XML配置文件来定义Bean,然后通过@Autowired或@Resource等注解来进行依赖注入。

bean的作用域

在Spring框架中,Bean的作用域(Scope)指定了Bean实例的创建和销毁方式,影响Bean实例的生命周期和可见性。Spring框架中常用的Bean作用域包括以下几种:

  1. singleton(单例):在整个Spring容器中只创建一个Bean实例,所有的Bean引用都指向同一个Bean实例。

  2. prototype(原型):每次调用getBean()方法时都会创建一个新的Bean实例,每个Bean引用都指向不同的Bean实例。

  3. request(请求):每个HTTP请求都会创建一个新的Bean实例,适用于Web应用中与HTTP请求相关的Bean。

  4. session(会话):每个HTTP会话(Session)都会创建一个新的Bean实例,适用于Web应用中与HTTP会话相关的Bean。

  5. global session(全局会话):通常用于基于Portlet的Web应用中,表示整个Portlet应用中的全局会话。

  6. application(应用程序):在整个Web应用中只创建一个Bean实例,所有的Bean引用都指向同一个Bean实例。

单例bean是否线程安全

单例Bean在Spring容器中只会创建一个实例,所有的请求都会共享同一个实例,因此单例Bean是线程共享的,但并不是线程安全的。

单例模式

懒汉式单例模式(线程不安全版):


public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

上述代码中的getInstance()方法是单例模式的入口,如果instance为空,就创建一个新的Singleton实例。这种实现方式是线程不安全的,因为多个线程可能同时调用getInstance()方法,导致创建多个Singleton实例。

懒汉式单例模式(线程安全版):


public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

上述代码中的getInstance()方法使用了synchronized关键字,保证了线程安全。但是这种实现方式会导致性能问题,因为多个线程需要等待获取锁。

饿汉式单例模式:


public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}

上述代码中的instance是在类加载时就创建好的,保证了线程安全和性能。但是这种实现方式可能会导致资源浪费,因为即使应用程序并不需要使用Singleton实例,也会在类加载时创建它。

spring用到了什么设计模式

  1. 单例模式:Spring容器中管理的Bean默认是单例模式,保证了Bean实例的唯一性和全局访问性。

  2. 工厂模式:Spring框架中的BeanFactory和ApplicationContext接口都是工厂模式的应用,用于管理和创建Bean实例。

  3. 代理模式:Spring AOP(面向切面编程)基于代理模式,使用动态代理技术来实现切面的横向逻辑。

  4. 模板方法模式:Spring框架中的JdbcTemplate和HibernateTemplate都是模板方法模式的应用,提供了一种简单易用的数据库访问方式。

  5. 观察者模式:Spring框架中的事件机制基于观察者模式,通过发布-订阅模式来实现Bean之间的松耦合。

  6. 适配器模式:Spring MVC框架中的HandlerAdapter就是适配器模式的应用,用于将请求适配到对应的Controller处理方法。

  7. 策略模式:Spring框架中的BeanPostProcessor接口和AOP的Advice接口都是策略模式的应用,用于动态修改Bean的行为。

ApplicationContext和BeanFactory的区别

ApplicationContext是BeanFactory的子接口,提供了更多的功能和特性。虽然ApplicationContext的启动时间和内存占用比BeanFactory多一些,但是它在应用程序运行时可以提高性能和响应速度,因为所有的Bean已经预先实例化好了。因此,开发人员需要根据具体的业务需求和性能要求选择合适的容器。

事务

Spring框架提供了对事务的支持,通过将事务管理交给Spring容器来实现事务的控制和管理。Spring事务管理的核心是TransactionManager接口,用于管理事务的生命周期和控制事务的提交和回滚。

实现方式

  1. 声明式事务:采用注解或XML配置的方式,在方法或类级别上声明事务的属性,Spring容器根据配置自动管理事务。
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    public void transfer(String from, String to, double amount) {
        userDao.withdraw(from, amount);
        userDao.deposit(to, amount);
    }
}
  1. 编程式事务:通过编写Java代码来显式地控制事务的开启、提交和回滚,需要手动处理事务的细节,灵活性高。
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private UserDao userDao;

    public void transfer(String from, String to, double amount) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                userDao.withdraw(from, amount);
                userDao.deposit(to, amount);
            }
        });
    }
}

隔离级别

事务隔离级别定义了多个事务之间的隔离程度,即一个事务对其他事务的影响。Spring事务管理支持四种隔离级别,分别是:

  • 未提交读(READ_UNCOMMITTED):事务未提交的数据修改可以被其他事务读取,可能会导致脏读、不可重复读和幻读等问题。

  • 已提交读(READ_COMMITTED):事务提交后的数据修改可以被其他事务读取,可以避免脏读,但可能会出现不可重复读和幻读等问题。

  • 可重复读(REPEATABLE_READ):事务中查询的数据会对其他事务加锁,保证其他事务不能修改该数据,避免了脏读和不可重复读,但可能会出现幻读。

  • 串行化(SERIALIZABLE):所有事务都按顺序串行执行,避免了所有并发问题,但对性能的影响较大。

传播级别

事务传播行为定义了多个事务之间的关系,即在一个事务中嵌套另一个事务时,如何处理事务的提交和回滚。Spring事务管理支持多种传播行为,包括:

  • PROPAGATION_REQUIRED:当前方法必须运行在一个事务中,如果存在事务,则加入该事务,否则新建一个事务。

  • PROPAGATION_REQUIRES_NEW:当前方法必须运行在一个新的事务中,如果存在事务,则将该事务挂起,重新开启一个新的事务。

  • PROPAGATION_SUPPORTS:当前方法支持运行在一个事务中,如果存在事务,则加入该事务,否则以非事务方式运行。

  • PROPAGATION_NOT_SUPPORTED:当前方法不支持运行在一个事务中,如果存在事务,则将该事务挂起,以非事务方式运行。

  • PROPAGATION_NEVER:当前方法必须以非事务方式运行,如果存在事务,则抛出异常。

  • PROPAGATION_MANDATORY:当前方法必须运行在一个事务中,如果不存在事务,则抛出异常。

  • PROPAGATION_NESTED:当前方法必须运行在一个嵌套事务中,如果不存在事务,则新建一个事务,如果存在事务,则在嵌套事务中运行。

优点

  1. 简化事务管理:Spring框架的事务管理机制能够自动处理事务的开启、提交和回滚等细节,减少了开发人员的工作量,降低了出错的风险。

  2. 支持声明式事务:Spring框架支持声明式事务,通过注解或XML配置来声明事务的属性,提高了代码的可读性和可维护性。

  3. 支持多种数据访问方式:Spring框架的事务管理可以支持多种数据访问方式,包括JDBC、Hibernate、MyBatis等,无需关心具体实现细节,提高了应用程序的可移植性和可扩展性。

  4. 提供了多种事务隔离级别和传播行为:Spring框架提供了多种事务隔离级别和传播行为,可以根据业务需求选择合适的事务隔离级别和传播行为,提高了应用程序的性能和可靠性。

  5. 支持分布式事务管理:Spring框架支持分布式事务管理,可以在多个数据源之间协调事务的提交和回滚,保证数据的一致性和完整性。

三要素

  • 数据源:事务性资源,被处理的信息。
  • 事务管理器:事务的管家,管理事务的打开、提交、回滚等。
  • 事务应用和属性配置:标识对象是否参与事务,如何参与事务等。

spring mvc请求处理

用户点击某个请求路径,发起一个 HTTP request 请求,该请求会被提交到 DispatcherServlet(前端控制器);
由 DispatcherServlet 请求一个或多个 HandlerMapping(处理器映射器),并返回一个执行链(HandlerExecutionChain)。
DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器);
HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(常称为 Controller);
Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC的底层对象,包括 Model 数据模型和 View 视图信息);
HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;
DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析;
ViewResolver 根据 View 信息匹配到相应的视图结果,并返回给 DispatcherServlet;
DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图);
视图负责将结果显示到浏览器(客户端)。

设计模式

设计模式及其在 Spring 中的应用:

单例模式(Singleton):Spring 容器默认会把所有的 Bean 都创建成单例,确保在应用中只有一个实例。
工厂模式(Factory):Spring 中使用工厂模式来创建 Bean,即通过工厂方法或工厂类创建对象,而不是直接使用 new 关键字创建对象。
代理模式(Proxy):Spring AOP 的实现基于 JDK 动态代理和 CGLIB 动态代理,对 Bean 进行增强。
模板方法模式(Template Method):Spring 中的 JdbcTemplate 就是基于模板方法模式实现的,提供了一些通用的数据库操作方法,减少了重复代码的编写。
观察者模式(Observer):Spring 中的事件驱动模型就是基于观察者模式实现的,当某个事件发生时,容器会通知所有监听该事件的监听器。
适配器模式(Adapter):Spring MVC 中的 HandlerAdapter 就是一个适配器,用于将不同类型的 Controller 适配成统一的处理器处理请求。
迭代器模式(Iterator):Spring 中的 JdbcTemplate 和 HibernateTemplate 都是基于迭代器模式实现的,可以对结果集进行迭代操作。
策略模式(Strategy):Spring Security 中的 AuthenticationManager 就是一个策略模式的应用,根据不同的认证策略,选择不同的认证方法。
外观模式(Facade):Spring 中的 Facade 模式主要应用于对复杂的子系统进行简化操作,例如 Spring 的 JmsTemplate 对 JMS 进行了封装,简化了 JMS 的使用。
装饰器模式(Decorator):Spring 中的 BeanWrapper 就是一个装饰器,可以对 Bean 进行装饰,提供一些额外的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值