Spring学习笔记

本文详细介绍了Spring框架的核心概念,包括bean与Spring容器的关系、容器配置元数据、依赖注入以及面向切面编程(AOP)。通过XML和注解两种方式展示了bean的配置,深入探讨了AOP的原理和实践,包括基于XML的AOP配置和基于注解的AOP配置。此外,还涵盖了Spring的模块、JdbcTemplate的使用以及Spring的新特性,如WebSocket支持和Java 8的兼容性。
摘要由CSDN通过智能技术生成

概述

耦合:类间的依赖
方法间的依赖
解耦:降低程序间的依赖关系
实际开发中应该做到:编译器不依赖,运行时才依赖
解耦的思路:
第一步,使用反射来创建对象,而避免使用new关键字
在这里插入图片描述
但这样还存在问题,驱动的描述字符串是写死的,如果需要切换其他数据库,则需要修改源码,不符合设计原则,解决办法:
第二步:通过读取配置文件来获取要创建的对象全限定类名

bean与spring容器的关系

在这里插入图片描述
bean配置信息定义了Bean的实现及依赖关系,spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载、实例化Bean,并建立Bean和Bean的依赖关系,最后将这些准备就绪的Bean放到Bean缓存池中,以供外层应用程序进行调用。

容器

Spring自带了多个容器实现,可以归为两种不同的类型。bean工 厂(由org.springframework. beans. factory.beanFactory接口定义)是最简单 的容器,提供基本的DI支持。应用上下文 (由org.springframework.context.ApplicationContext接口定义)基于 BeanFactory构建,并提供应用框架级别的服务,例如从属性文件解析文本信息以及发布应用 事件给感兴趣的事件监听者。
虽然我们可以在bean工厂和应用上下文之间任选一种,但bean工厂对大多数应用来说往往太 低级了,因此,应用上下文要比bean工厂更受欢迎。

应用上下文

Spring通过应用上下文(Application Context)装载bean的定义并把它们组装起来。Spring应用 上下文全权负责对象的创建和组装。Spring自带了多种应用上下文的实现,它们之间主要的 区别仅仅在于如何加载配置。
因为knights.xml中的bean是使用XML文件进行配置的,所以选择 ClassPathXmlApplicationContext[1]作为应用上下文相对是比较合适的。该类加载位 于应用程序类路径下的一个或多个XML配置文件。程序清单1.8中的main()方法调 用ClassPathXmlApplicationContext加载knights.xml,并获得Knight对象的引用。
程序清单1.8 KnightMain.java加载包含Knight的Spring上下文
在这里插入图片描述
这里的main()方法基于knights.xml文件创建了Spring应用上下文。随后它调用该应用上下文 获取一个ID为knight的bean。得到Knight对象的引用后,只需简单调用embarkOnQuest() 方法就可以执行所赋予的探险任务了。注意这个类完全不知道我们的英雄骑士接受哪种探险 任务,而且完全没有意识到这是由BraveKnight来执行的。只有knights.xml文件知道哪个骑 士执行哪种探险任务。

beanFactory和ApplicationContext区别

ApplicationContext:在构建核心容器时,创建对象采取的策略是立即加载的方式,也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象(单例对象下适用)
beanFactory:在构建核心容器时,创建对象采取的策略是延迟加载的方式,只有使用id获取bean对象的时候,才真正的创建对象(多例对象适用)

应用上下文类型

Spring自带了多种类型的应用上下文。常见的如下:
AnnotationConfigApplicationContext:从一个或多个基于Java的配置类中加载Spring应用上下文。
在这里插入图片描述
AnnotationConfigWebApplicationContext:从一个或多个基于Java的配置类中加载Spring Web应用上下文。
**ClassPathXmlApplicationContext:**从所有类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源。 要求配置文件必须在类路径下,否则加载不了
在这里插入图片描述
FileSystemXmlapplicationcontext:从指定的文件系统路径下 的一个或多个XML配置文件 中加载上下文定义。 (必须有访问权限)在这里插入图片描述
XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载上 下文定义。
应用上下文准备就绪之后,我们就可以调用上下文的getBean()方法从Spring容器中获取 bean。
Spring容器中的bean的生命周期
在这里插入图片描述
详细描 述如下:
1.Spring对bean进行实例化;
2.Spring将值和bean的引用注入到bean对应的属性中;
3.如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()方 法;
4.如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将 BeanFactory容器实例传入;
5.如果bean实现了ApplicationContextAware接口,Spring将调 用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来; 6.如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()方法;
7.如果bean实现了InitializingBean接口,Spring将调用它们的after
PropertiesSet()方法。类似地,如果bean使用init-method声明了初始化方法,该方 法也会被调用;
8.如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitialization()方法;
9.此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中, 直到该应用上下文被销毁;
10.如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同 样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。

容器配置元数据(bean配置)

装配: 创建应用组件之间协作的行为。
1.基于xml文件配置bean:
Spring有多种装配bean的方式,采用 XML是很常见的一种装配方式。对于基于XML的配置,Spring 2.0以后使用Schema的格式,使得不同类型的配置拥有了自己的命名空间,是配置文件更具扩展性。
xml配置参数详解
①默认命名空间:它没有空间名,用于Spring Bean的定义;
②xsi命名空间:这个命名空间用于为每个文档中命名空间指定相应的Schema样式文件,是标准组织定义的标准命名空间;
③aop命名空间:这个命名空间是Spring配置AOP的命名空间,是用户自定义的命名空间。
命名空间的定义分为两个步骤:第一步指定命名空间的名称;第二步指定命名空间的Schema文档样式文件的位置,用空格或回车换行进行分分隔。
一般情况下,Spring IOC容器中的一个Bean即对应配置文件中的一个<bean>,这种镜像对应关系应该容易理解。其中id为这个Bean的名称,通过容器的getBean(“foo”)即可获取对应的Bean,在容器中起到定位查找的作用,是外部程序和Spring IOC容器进行交互的桥梁。class属性指定了Bean对应的实现类。

下面是基于XML的配置文件定义了两个简单的Bean:在这里插入图片描述
2.基于注解定义bean:
Spring容器成功启动的三大要件分别是:Bean定义信息、Bean实现类以及Spring本身。

如果采用基于XML的配置,Bean定义信息和Bean实现类本身是分离的,而采用基于注解的配置方式时,Bean定义信息即通过在Bean实现类上标注注解实现。

下面是使用注解定义一个DAO的Bean:

package com.guazi.anno;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
//①通过Repository定义一个DAO的Bean
@Component("userDao")
public class UserDao {
   

}

在①处,我们使用 @Component 注解在UserDao类声明处对类进行标注,它可以被Spring容器识别,Spring容器自动将POJO转换为容器管理的Bean。

它和以下的XML配置是等效的:

<bean id="userDao" class="com.guazi.anno.UserDao"/>

除了@Component以外,Spring提供了3个功能基本和@Component等效的注解,它们分别用于对DAO、Service及Web层的Controller进行注解,所以也称这些注解为Bean的衍型注解:(类似于xml文件中定义Bean<bean id=" " class=" "/>
@Repository:用于对DAO实现类进行标注;
@Service:用于对Service实现类进行标注;
@Controller:用于对Controller实现类进行标注;
之所以要在@Component之外提供这三个特殊的注解,是为了让注解类本身的用途清晰化,此外Spring将赋予它们一些特殊的功能。
关于三个注解的详细使用规则见:
https://www.cnblogs.com/haoyul/p/9875392.html

1.2.1 使用注解配置信息启动spring容器
spring容器默认情况下没有开启基于注解的装配。如果要使用基于java注解的元数据,我们需要首先在xml文件中引入context命名空间.然后使用<context:annotation-config/>元素开启spring的注解配置元
数据模板如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>
   <!-- bean definitions go here -->

</beans>

关于注解配置元<context:annotation-config/>的讲解:
https://www.cnblogs.com/leduo-zuul/p/10685904.html
下例中使用了 <context:component-scan/> 后,就可以将 <context:annotation-config/> 移除了

此例中,Spring提供了一个context的命名空间,然后提供了通过扫描类包以应用注解定义Bean的方式:

<?xml version="1.0" encoding="UTF-8" ?>
<!--①声明context的命名空间-->
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd"
         >
    <!--②扫描类包以应用注解定义的Bean-->
   <context:component-scan base-package="com.guazi.anno"/>
   <bean class="com.guazi.anno.LogonService"></bean>
   <!-- context:component-scan base-package="com.guazi" resource-pattern="anno/*.class"/ -->
   <!-- context:component-scan base-package="com.guazi">
       <context:include-filter type="regex" expression="com\.guazi\.anno.*Dao"/>
       <context:include-filter type="regex" expression="com\.guazi\.anno.*Service"/>
       <context:exclude-filter type="aspectj" expression="com.guazi..*Controller+"/>
   </context:component-scan -->
</beans>

在①处声明context命名空间,在②处即可通过context命名空间的component-scan的base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里的所有类,并从类的注解信息中获取Bean的定义信息。

如果仅希望扫描特定的类而非基包下的所有类,你们可以使用resource-pattern属性过滤特定的类,如下所示:

< context:component-scan base-package="com.guazi" resource-pattern="anno/*.class"/ >

这里我们将基类包设置为com.guazi,默认情况下resource-pattern属性的值为"**/*.class",即基类包里的所有类。这里我们设置为"anno/*.class",则Spring仅会扫描基包里anno子包中的类。

常用的注解:
Required注解:该注解标注到bean的setter上,意味着bean的该属性必须由spring进行注入。如果没有注入的话,spring容器在启动的时候就会报错.
Autowired注解:Autowired可以标注在字段、setter、构造函数上。默认是按类型进行装配。具体的工作流程如下:
1.如何一个字段、属性、构造方法被Autowired标注,spring去容器中找相应的类型的bean
2.如果找不到对应类型的bean,直接报错
3.如果找到了多个该类型的bean,会按照名字进行装,如果无法按照名字装配则报错
Qualifier注解: 与Autowired注解配合使用,可以使Autowired注解一开始就按照名字进行装配.
JSR-250注解
jsr-250提供了三个注解:PostConstruct、PreDestroy、Resource
PostConstruct相当于之前介绍的init-method属性,指定bean的初始化方法
PreDestroy相当于之前介绍的destroy-method属性,指定bean的销毁方法
Resource类似于Autowired注解,不过Resource是由jdk提供了,Autowired是spring提供的。Resource直接默认情况下先按照名字进行注入,如果在容器中找不到相应的名字,就会按照类型装配
JSR-330对标准注解的变体:
在这里插入图片描述
在这里插入图片描述

3.基于Java提供bean定义:
在普通的POJO类中只要标注@Configuration注解,就可以为spring容器提供Bean定义的信息了,每个标注了@Bean的类方法都相当于提供了一个Bean的定义信息。

package com.baobaotao.conf;

import org.springframework.context.annotation.Bean;
import org
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值