【笔记】第一阶段 模块二 :Spring IOC应用回顾

1.spring IOC基础

1.1.BeanFactory与ApplicationContext区别
BeanFactory:Spring框架中IoC容器的顶层接⼝,SpringIOC的基础容器,它只是⽤来定义⼀些基础功能,定义⼀些基础规范
ApplicationContext:是容器的⾼级接⼝,⽐BeanFactory要拥有更多的功能,⽐如说国际化⽀持和资源访问(xml,java配置类)等等

image.png

1.2 spring xml文件头信息解释

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd">
  
  
</beans>

xmlns="http://www.springframework.org/schema/beans"
声明xml文件默认的命名空间,表示未使用其他命名空间的所有标签的默认命名空间,由于beans是spring ioc基础功能,所以前缀是默认省略的

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
声明XML Schema实例,声明后就可以使用schemaLocation属性。

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
第一个值表示需要使用的命名空间。第二个值表示供命名空间使用的XML schema的位置。
上面配置的命名空间指定xsd规范文件,这样你在进行下面具体配置的时候就会根据这些xsd规范文件给出相应的提示,比如说每个标签是怎么写的,都有些什么属性是都可以智能提示的,在启动服务的时候也会根据xsd规范对配置进行校验

如果要添加其他功能,例如aop,则如下写法

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    ...

</beans>

添加 xmlns:aop="http://www.springframework.org/schema/aop" 以及schmaLocation中的
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
命名空间前缀为aop,入后就可以在包裹的范围内使用<aop>标签,当然前缀名也可以取别的,例如aop1等等,只是在使用标签时候会对应的变化

1.3spring IOC容器启动方式

image.png

2.spring IOC纯xml模式回顾

2.1.srping IOC容器启动方式
javaSE应用:

// 通过读取classpath下的xml文件来启动容器(xml模式SE应用下推荐)
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

java web应用容器启动:
在web.xml中配置ioc容器以及监听器以及在pom.xml中引入spring web相关功能,

<web-app>
  <display-name>Archetype Created Web Application</display-name>


  <!--配置Spring ioc容器的配置文件-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <!--使用监听器启动Spring的IOC容器-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.1.12.RELEASE</version>
    </dependency>

2.2xml模式下实例化bean的三种方式
(1).⽆参构造函数
通过反射调⽤⽆参构造函数来创建对象。如果类中没有⽆参构造函数,将创建失败

 <!--Spring ioc 实例化Bean的三种方式-->
    <!--方式一:使用无参构造器(推荐)-->
    <bean id="connectionUtils" class="com.lagou.edu.utils.ConnectionUtils"></bean>

(2)静态⽅法创建
CreateBeanFactory会提供⼀个创建对象的⽅法,恰好这个⽅法是static修饰的⽅法

<!--另外两种方式是为了我们自己new的对象加入到SpringIOC容器管理-->
    <!--方式二:静态方法-->
   <bean id="connectionUtils" class="com.lagou.edu.factory.CreateBeanFactory" factory-method="getInstanceStatic"/>

(3)实例化方法创建
和上⾯静态⽅法创建其实类似,区别是⽤于获取对象的⽅法不再是static修饰的了,⽽是
类中的⼀ 个普通⽅法。

<!--方式三:实例化方法-->
    <bean id="createBeanFactory" class="com.lagou.edu.factory.CreateBeanFactory"></bean>
    <bean id="connectionUtils" factory-bean="createBeanFactory" factory-method="getInstance"/>

2.3 Bean的作用范围与生命周期
在spring框架管理Bean对象的创建时,Bean对象默认都是单例的,可以通过scope来配置不同的作用范围,常用作⽤范围就是singleton(单例模式)和prototype(原型模式,也叫多例模式)

<bean id="transferService"
class="com.lagou.service.impl.TransferServiceImpl" scope="singleton">
</bean>

单例模式:singleton
对象出⽣:当创建容器时,对象就被创建了。
对象活着:只要容器在,对象⼀直活着。
对象死亡:当销毁容器时,对象就被销毁了。
⼀句话总结:单例模式的bean对象⽣命周期与容器相同。

多例模式:prototype
对象出⽣:当使⽤对象时,创建新的对象实例。
对象活着:只要对象在使⽤中,就⼀直活着。
对象死亡:当对象⻓时间不⽤时,被java的垃圾回收器回收了。
⼀句话总结:多例模式的bean对象,spring框架只负责创建,不负责销毁。

2.4 DI 依赖注⼊的xml配置
2.4.1 set⽅法注⼊
set⽅法注⼊:它是通过类成员的set⽅法实现数据的注⼊。(使⽤最多的)示例如下

<!--set注入使用property标签,如果注入的是另外一个bean那么使用ref属性,如果注入的是普通值那么使用的是value属性-->
        <property name="ConnectionUtils" ref="connectionUtils"/>
        <property name="name" value="zhangsan"/>
        <property name="sex" value="1"/>
        <property name="money" value="100.3"/>

在使⽤set⽅法注⼊时,需要使⽤ property 标签,该标签属性如下:
name:指定注⼊时调⽤的set⽅法名称。(注:不包含set这三个字⺟,druid连接池指定属性名称)
value:指定注⼊的数据。它⽀持基本类型和String类型。
ref:指定注⼊的数据。它⽀持其他bean类型。写的是其他bean的唯⼀标识

  • 复杂数据类型的set方法注入,如下
<property name="myArray">
            <array>
                <value>array1</value>
                <value>array2</value>
                <value>array3</value>
            </array>
        </property>

        <property name="myMap">
            <map>
                <entry key="key1" value="value1"/>
                <entry key="key2" value="value2"/>
            </map>
        </property>

        <property name="mySet">
            <set>
                <value>set1</value>
                <value>set2</value>
            </set>
        </property>

        <property name="myProperties">
            <props>
                <prop key="prop1">value1</prop>
                <prop key="prop2">value2</prop>
            </props>
        </property>

2.4.2构造函数注⼊
构造函数注⼊:顾名思义,就是利⽤带参构造函数实现对类成员的数据赋值。

<!--name:按照参数名称注入,index按照参数索引位置注入-->
        <constructor-arg name="connectionUtils" ref="connectionUtils"/>
        <constructor-arg name="name" value="zhangsan"/>
        <constructor-arg name="sex" value="1"/>
        <constructor-arg name="money" value="100.6"/>

涉及的标签是 constructor-arg ,该标签有如下属性:
name:⽤于给构造函数中指定名称的参数赋值。
index:⽤于给构造函数中指定索引位置的参数赋值。
value:⽤于指定基本类型或者String类型的数据。
ref:⽤于指定其他Bean类型的数据。写的是其他bean的唯⼀标识

3. xml与注解相结合模式

*第三⽅jar中的bean定义在xml,⽐如德鲁伊数据库连接池;⾃⼰开发的bean定义使⽤注解

  • xml中标签与注解的对应(IoC)


    image.png

DI依赖注入怎么实现?
(1)@Autowired(推荐使⽤)
@Autowired为Spring提供的注解,需要导⼊包
org.springframework.beans.factory.annotation.Autowired。
@Autowired采取的策略为按照类型注⼊,当⼀个类型有多个bean值的时候,需要配合着@Qualifier使⽤
(2)@Resource
@Resource 注解由 J2EE 提供,需要导⼊包 javax.annotation.Resource。
@Resource 默认按照 ByName ⾃动注⼊
指定了 name,则从上下⽂中查找名称(id)匹配的bean进⾏装配
指定了 type,则从上下⽂中找到类似匹配的唯⼀bean进⾏装配,找不到或是找到多个,
都会抛出异常
3.1 自己开发bean使用注解
如下例子
bean标签对应@Component注解.由于是在service层,所以注解使用@Service("transferService")
ref依赖,原先使用的set方法注入,现在对应注解中的自动装配 @Autowire @Qualifier("accountDao")

 </bean>
    <bean id="transferService" class="com.lagou.edu.service.impl.TransferServiceImpl">
        <!--set+ name 之后锁定到传值的set方法了,通过反射技术可以调用该方法传入对应的值-->
        <property name="AccountDao" ref="accountDao"></property>
    </bean>
@Service("transferService")
public class TransferServiceImpl implements TransferService {


    // 最佳状态
    // @Autowired 按照类型注入 ,如果按照类型无法唯一锁定对象,可以结合@Qualifier指定具体的id
    @Autowired
    @Qualifier("accountDao")
    private AccountDao accountDao;

注意:在使用了注解后,注解怎么被框架发现?
用注解后,在xml配置扫描
首先 xml文件头中添加xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
再配置扫描

 <!--开启注解扫描,base-package指定扫描的包路径-->
    <context:component-scan base-package="com.lagou.edu"/>

**3.2 第三方jar中bean使用xml

    <context:property-placeholder location="classpath:jdbc.properties"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

4.spring IOC 纯注解模式

@Configuration 注解,表名当前类是⼀个配置类
@ComponentScan 注解,替代 context:component-scan
@PropertySource,引⼊外部属性配置⽂件
@Import 引⼊其他配置类
@Value 对变量赋值,可以直接赋值,也可以使⽤ ${} 读取资源配置⽂件中的信息
@Bean 将⽅法返回对象加⼊ SpringIOC 容器

示例如下

// @Configuration 注解表明当前类是一个配置类
@Configuration
@ComponentScan({"com.lagou.edu"})
@PropertySource({"classpath:jdbc.properties"})
/*@Import()*/
public class SpringConfig {

    @Value("${jdbc.driver}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;


    @Bean("dataSource")
    public DataSource createDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driverClassName);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        return  druidDataSource;
    }
}

5.高级特性之Lazy-init

适用范围: singleton bean
默认情况:ApplicationContext 容器启动服务器时将所有 singleton bean 提前进⾏实例化
设置方法:
xml配置

<bean id="testBean" calss="cn.lagou.LazyBean" lazy-init="true" />

注解模式加@Lazy注解即可,默认是开启
使用场景:不常使⽤的 Bean 设置延迟加载,这样偶尔使⽤的时候再加载,不必要从⼀开始该 Bean 就占⽤资源;⼀定程度提⾼容器启动和运转性能

6.高级特性之FactoryBean 和 BeanFactory

BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚,具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext
FactoryBeanFactoryBean可以⽣成某⼀个类型的Bean实例,我们可以借助于它⾃定义Bean的创建过程

// 可以让我们⾃定义Bean的创建过程(完成复杂Bean的定义)
public interface FactoryBean<T> {
 @Nullable
 // 返回FactoryBean创建的Bean实例,如果isSingleton返回true,则该实例会放到Spring容器
的单例对象缓存池中Map
 T getObject() throws Exception;
 @Nullable
 // 返回FactoryBean创建的Bean类型
 Class<?> getObjectType();
 // 返回作⽤域是否单例
 default boolean isSingleton() {
 return true;
 } }

7.高级特性之后置处理器

未完待续......

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358

推荐阅读更多精彩内容