Spring学习


IOC

IoC也称为依赖注入DI,将对象的创建、初始化、销毁等操作交给Spring容器管理

容器

  • org.springframework.beansorg.springframework.context包是 Spring Framework 的 IoC 容器的基础
  • BeanFactory提供配置框架和基本功能,ApplicationContext包括BeanFactory的所有功能,提供更多功能

ApplicationContext和BeanFactory的功能

特征 BeanFactory ApplicationContext
Bean实例化/装配 是的 是的
集成的生命周期管理 是的
自动BeanPostProcessor注册 是的
自动BeanFactoryPostProcessor注册 是的
方便MessageSource的访问(国际化) 是的
内置ApplicationEvent发布机制 是的

ApplicationContext

几种实现类
  • ClassPathXmlApplicationContext:从classpath下寻找xml配置文件并实例化

    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    
  • FileSystemXmlApplicationContext:从文件系统下寻找xml配置文件并实例化

    ApplicationContext context = new FileSystemXmlApplicationContext("C://beans.xml");
    
  • AnnotationConfigApplicationContext:使用Java配置类实例化

     ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
    
获取Bean的基本方式
  • getBean(String name):根据对象名获取,需要强制类型转换
  • <T> T getBean(Class<T> requiredType):根据类的类型获取,如果存在多个实例会报错
  • <T> T getBean(String name, Class<T> requiredType):根据对象名以及类的类型获取

Xml配置

基本结构
  • id是用于标识一个Bean的字符串
  • class是Bean的所属类的全限定类名
<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

Bean

容器管理一个或多个bean,bean都是由配置元数据生成的

Bean的命名

  • 使用id命名只能指定一个名称
  • 使用name命名可以指定多个名称使用逗号分隔
  • 如果不显式提供名称,则容器会自动为该bean生成一个唯一的名称,驼峰命名

在Bean定义之外使用别名

通常在name中为bean提供多个名称,但有时需要在别的地方提供别名,可以使用alias标签

<alias name="fromName" alias="toName"/>

上面代码为名称为fromName的bean定义了一个新的别名toName

Bean的实例化

使用构造方法实例化

使用idname指定名称,使用class指定bean的类

<bean id="exampleBean" class="examples.ExampleBean"/>

<bean name="anotherExample" class="examples.ExampleBeanTwo"/>

如果参数的类型都不一致,则在<constructor-arg>中指定直接指定参数,无需指定参数的index或类型

<beans>
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg ref="beanTwo"/>
        <constructor-arg ref="beanThree"/>
    </bean>
    <bean id="beanTwo" class="x.y.ThingTwo"/>
    <bean id="beanThree" class="x.y.ThingThree"/>
</beans>
指定构造方法参数的索引

使用index属性指定参数的位置

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>
指定构造方法参数的类型

使用type属性指定参数的类型

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>
指定构造方法参数的名称

使用name属性指定参数的名称,此功能要在debug flag为启用的状态下才能生效,也可以使用@ConstructorProperties注解显式命名参数

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>
使用静态工厂方法实例化

调用类的静态方法创建bean,使用class属性指定包含静态工厂方法的类,使用factory-method指定工厂方法的名称

<bean id="clientService" class="examples.ClientService" factory-method="createInstance"/>
public class ClientService {
    private static ClientService clientService = new ClientService();
    private ClientService() {}

    public static ClientService createInstance() {
        return clientService;
    }
}
使用实例工厂实例化

调用现有bean的实例方法创建新的bean,使用factory-bean属性指定bean的名称,使用factory-method指定工厂方法的名称

<bean id="serviceLocator" class="examples.DefaultServiceLocator"></bean>

<bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/>
public class DefaultServiceLocator {

    private static ClientService clientService = new ClientServiceImpl();

    public ClientService createClientServiceInstance() {
        return clientService;
    }
}

依赖注入

构造方法注入
根据参数类型自动匹配

如果参数的类型都不一致,则在<constructor-arg>中指定直接指定参数,无需指定参数的index或类型

<beans>
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg ref="beanTwo"/>
        <constructor-arg ref="beanThree"/>
    </bean>
    <bean id="beanTwo" class="x.y.ThingTwo"/>
    <bean id="beanThree" class="x.y.ThingThree"/>
</beans>
指定构造方法参数的索引

使用index属性指定参数的位置

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>
指定构造方法参数的类型

使用type属性指定参数的类型

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>
指定构造方法参数的名称

使用name属性指定参数的名称,此功能要在debug flag为启用的状态下才能生效,也可以使用@ConstructorProperties注解显式命名参数

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>
Setter注入

是通过无参构造器或无参数的工厂方法实例化bean后,调用bean的setter方法注入bean

<bean id="exampleBean" class="examples.ExampleBean">
    <property name="years" value=7500000></property>
    <property name="ultimateAnswer" value="42"></property>
</bean>
使用构造函数注入还是Setter注入
  • 可以混合使用两种方法,通常将必须的依赖项使用构造函数注入,可选的依赖项使用setter注入
  • 可以使用@Required注解标注在对应的setter方法上,确保该依赖项是必须的,否则会报错
  • 构造方法注入通常可以确保所需的依赖不是null
  • 特定的类可以使用适合的方法,如果一个第三方类没有提供setter方法,那么只能使用构造函数

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/244735.html

(0)
上一篇 2022年4月17日
下一篇 2022年4月17日

相关推荐

发表回复

登录后才能评论