JavaEE——Spring:对Bean的管理

时间:2024-10-10 09:48:48

1.IOC(控制反转)和DI(依赖注入)

  • IOC:控制反转,将对象的创建权反转给Spring
  • DI:依赖注入,前提必须有IOC的环境,Spring在管理类的时候会将类的依赖的属性注入(设置)进来
  • 面向对象的时候类之间关系:

1.依赖

class A{
}
class B{
      public void xxx(A a){}
}

2.继承

class A{
}
class B extends A{
}

3.集合:has a

2.依赖注入示例

在这里插入图片描述
传统操作设置name:
在这里插入图片描述
采用DI(依赖注入):
在这里插入图片描述
在这里插入图片描述

的工厂类

3.工厂结构图

在这里插入图片描述
ApplicationContext和BeanFactory的区别

  • ApplicationContext继承了BeanFactory
  • BeanFactory在调用getBean的时候才会生成类的实例,ApplicationContext在加载配置文件的时候就会将Spring管理的类都实例化

3.(老版本)

BeanFactory在调用getBean的时候才会生成类的实例

3.(新版本)

ApplicationContext继承了BeanFactory且在加载配置文件的时候就会将Spring管理的类都实例化,ApplicationContext有两个实现类:

  • ClassPathXMLApplicationContext:加载类路径下的配置文件
  • FileSystemXMLApplicationContext:加载文件系统的配置文件

的配置

4.的提示配置

4.1.的配置

在这里插入图片描述

4.1.的相关配置

4.1.2.1.<bean>标签的id和name配置
  • id:使用了约束中的唯一约束,里面不能出现特殊字符
  • name没有使用约束中的唯一约束(理论上是可以重复的,但实际开发中不能出现,会报错),可以出现特殊字符(和Struts1框架整合时要用name,因为Struts1中用了特殊字符)
  • class:要生成的实例的类的全路径
4.1.2.的生命周期配置
  • init-method:Bean被初始化的时候执行的方法
  • destroy-method:Bean被销毁时执行的方法(Bean是单例创建,工厂关闭)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
4.1.2.的作用范围配置(重点)

scope:Bean的作用范围

  • singleton:默认的,Spring会采用单例模式创建这个对象
  • prototype:多例模式,用一次new一个
  • request:应用在Web项目中,Spring创建这个类以后,将这个类存入到request范围中
  • session:应用在Web项目中,Spring创建这个类以后,将这个类存入到session范围中
  • globalsession:应用在Web项目中,必须在porlet环境(在一个地方登陆后在其他子网站登陆就不需要再登陆)下使用

的Bean管理

5.中Bean的实例化

5.1.1.静态工厂方法

调用静态工厂方法创建 Bean是将对象创建的过程封装到静态方法中,当客户端需要对象时, 只需要简单地调用静态方法,而不同关心创建对象的细节,要声明通过静态方法创建的 Bean,需要在 Bean 的 class 属性里指定拥有该工厂的方法的类,同时在 factory-method 属性里指定工厂方法的名称。最后使用 <constrctor-arg>元素为该方法传递方法参数

package com.xpu.bean_factory;

import java.util.HashMap;
import java.util.Map;

/**
 * 静态工厂方法:直接调用某一个类的静态方法就可以返回一个bean的实例
 */
public class StaticCarFactory {
	private static Map<String, Car> cars = new HashMap<>();
	
	static {
		cars.put("audi", new Car("audi",300000));
		cars.put("ford", new Car("ford",400000));
	}
	
	//静态工厂方法
	public static Car getCar(String name) {
		return cars.get(name);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
<!-- 通过静态方法工厂来配置Bean,注意不是配置静态方法工厂实例,而是Bean实例 -->
<!-- class属性指向静态方法工厂的Class
	 factory-method属性指向静态工厂的名字
	 constructor-arg如果工厂方法需要传入参数,则使用constructor-arg来配置参数
	 -->
<bean id="car1" class=".bean_factory.StaticCarFactory" factory-method="getCar">
	<constructor-arg value="audi"></constructor-arg>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5.1.2.实例工厂方法

将对象的创建过程封装到另外一个对象实例的方法里, 当客户端需要请求对象时,只需要简单的调用该实例方法而不需要关心对象的创建细节,要声明通过实例工厂方法创建的 Bean

  • 在 bean 的 factory-bean 属性里指定拥有该工厂方法的 Bean
  • 在 factory-method 属性里指定该工厂方法的名称
  • 使用 construtor-arg 元素为工厂方法传递方法参数
package com.xpu.bean_factory;

import java.util.HashMap;
import java.util.Map;

/**
 * 实例工厂的方法,即先需要创建工厂本身,再调用工厂的实例方法,再返回Bean实例
 */
public class InstanceCarFactory {
	private static Map<String, Car> cars = null;
	public InstanceCarFactory() {
		cars = new HashMap<>();
		cars.put("audi", new Car("audi",300000));
		cars.put("ford", new Car("ford",400000));
	}
	
	public Car getCar(String brand) {
		return cars.get(brand);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
<!-- 配置工厂的实例 -->
<bean id="carFactory" class=".bean_factory.InstanceCarFactory"></bean>

<!-- 通过实例工厂方法来配置Bean -->
<!-- factory-bean属性指向实例方法工厂的Class
	 factory-method属性指向实例工厂的名字
	 constructor-arg如果工厂方法需要传入参数,则使用constructor-arg来配置参数
 -->
<bean id="car2" factory-bean="carFactory" factory-method="getCar">
	<constructor-arg value="ford"></constructor-arg>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

5.1.

实现FactoryBean接口在Spring IOC容器中配置Bean,Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,即FactoryBean。工厂 Bean 跟普通Bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂 Bean 的 getObject 方法所返回的对象 ,示例如下:

package com.xpu.factory_spring;

import org.springframework.beans.factory.FactoryBean;

//自定义的FactoryBean需要实现Spring提供的FactoryBean接口
public class CarFactoryBean implements FactoryBean<Car> {

	private String brand;
	public void setBrand(String brand) {
		this.brand = brand;
	}
	
	//返回Bean的对象
	@Override
	public Car getObject() throws Exception {
		return new Car(brand, 500000);
	}

	//返回Bean的类型
	@Override
	public Class<?> getObjectType() {
		return Car.class;
	}
	
	//是否是单例的
	@Override
	public boolean isSingleton() {
		return true;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
<!-- 通过FactoryBean来配置Bean的实例
	 class执行FactoryBean的全类名
	 property配置的是FactoryBean的属性,但是返回的FactoryBean的getObject()方法返回的实例
	 -->
<bean id="car" class=".factory_spring.CarFactoryBean">
	<property name="brand" value="BMW"></property>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

5.1.4.基于注解的方式

接下来说说基于注解的方式配置Bean,这也是常见的方式:
组件扫描(component scanning):Spring能够从classpath下自动扫描,,侦测和实例化具有特定注解的组件,特定组件包括:

  • @Component:基本注解,标识了一个受 Spring 管理的组件
  • @Respository:标识持久层组件
  • @Service:标识服务层(业务层)组件
  • @Controller;标识表现层组件

对于扫描到的组件,Spring有默认的命名策略:使用非限定类名,第一个字母小写,也可以在注解中通过value属性值标识组件的名称。当在组件类上使用了特定的注解之后, 还需要在 Spring 的配置文件中声明需要扫描的包,而且不要忘记声明命名空间<context:component-scan>

<context:component-scan base-package=""></context:component-scan>
  • 1

base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里及其子包中的所有类。当需要扫描多个包时,可以使用逗号分隔,如果仅希望扫描特定的类而非基包下的所有类,可使用 resource-pattern 属性过滤特定的类,示例:

<!-- 可以通过resource-pattern可以指定扫描的资源 -->
<context:component-scan base-package="" resource-pattern="service/*.class" ></context:component-scan>
  • 1
  • 2
  • <context:include-filter> 子节点表示要包含的目标类
  • <context:exclude-filter> 子节点表示要排除在外的目标类
  • <context:component-scan> 下可以拥有若干个 <context:include-filter><context:exclude-filter> 子节点
<!-- context:exclude-filter就是排除哪些类 -->
<context:component-scan base-package="" use-default-filters="false">
	<context:exclude-filter type="annotation" expression=""/>
</context:component-scan>

<context:component-scan base-package="" use-default-filters="false">
	<context:include-filter type="annotation" expression=""/>
</context:component-scan>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

注意对于那些已经配置了注解的类,想要使自己的过滤器生效,就需要配置一个use-default-filters="false"要求不要使用默认的过滤器

<context:include-filter><context:exclude-filter> 子节点支持多种类型的过滤表达式:

类别 示例 说明
annotation 所有标注了XxxAnnotation的类,该类型采用目标类型是否标注了某个注解进行过滤
assinable 继承或者扩展XxxService的类,该类型采用目标类型是否继承或者拓展某个特定的类进行过滤
aspectj .*Service+ 所有类名以Service结束及继承或扩展它们的类,该类型采用aspectJ表达式进行过滤
regex .* 所有包下的类,该类型采用正则表达式根据类名进行过滤
custom 采用XxxTypeFilter通过代码的方式定义过滤规则。该类必须实现接口

5.的属性注入

在这里插入图片描述

5.2.1.构造方法的方式的属性注入

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2.方法的方式的属性注入

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

对象类型属性的注入
类中方法:value是设置普通类型的值,ref用来设置其他类的id或name

  • 构造方法方式设置对象类型属性:constructor-arg标签也有ref
  • set方法方式设置对象类型属性:用ref
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

5.2.名称空间属性的注入(Spring2.5以后的版本)

通过引入p名称空间完成属性的注入,写法如下:

  • 普通属性: p:属性名=“值”
  • 对象属性: p:属性名-ref=“值”

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2.的属性注入(Spring3.0以后的版本)

  • SpEL:Spring Expression Language,Spring表达式语言
  • 语法:#{SpEL}

注入普通属性
在这里插入图片描述
在这里插入图片描述
注入对象类型属性:
在这里插入图片描述
在这里插入图片描述

5.3.集合类型的属性注入

/**
 * 集合属性的注入
 */
public class CollectionBean {
    private String[] arrs;
    private List<String> list;
    private Set<String> set;
    private Map<String,String> map;

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setArrs(String[] arrs){
        this.arrs = arrs;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "arrs=" + Arrays.toString(arrs) +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                '}';
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

配置文件内容:

<!--Spring集合属性的注入-->
    <!--注入数组类型-->
    <bean id = "collectionBean" class="">
        <!--数组类型和list是一样的-->
        <property name="arrs">
            <list>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
            </list>
        </property>

        <!--注入list集合-->
        <property name="list">
            <list>
                <value>小可爱</value>
                <value>小靓仔</value>
                <value>小鸡儿</value>
            </list>
        </property>

        <!--注入set集合-->
        <property name="set">
            <set>
                <value>头发</value>
                <value>鼻子</value>
                <value>耳朵</value>
            </set>
        </property>

        <!--注入map集合-->
        <property name="map">
            <map>
                <entry key="小鸡" value="111"></entry>
                <entry key="小猫" value="333"></entry>
                <entry key="小狗" value="222"></entry>
            </map>
        </property>
    </bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

注入成功:
在这里插入图片描述

的分模块开发配置

6.1.分模块配置

6.1.1.在加载配置文件的时候,加载多个

在这里插入图片描述

6.1.2.在一个配置文件中引入多个配置文件

在这里插入图片描述
在这里插入图片描述