spring(1)

文章目录

  • IOC容器
    • IOC容器和beans的介绍
      • 实例化 Bean
      • BeanFactory:
      • ApplicationContext
    • 容器概述
      • 配置元数据
      • 实例化容器
      • 组合基于xml的配置元数据
      • 使用容器
    • bean的概述
      • 命名bean
        • 别名的使用
      • 实例化bean
        • 构造函数实例化
        • 静态工厂实例化
        • 实例工厂方法
        • bean 在运行时的实际类型
    • 依赖
      • 依赖注入

IOC容器

IOC容器和beans的介绍

IOC 容器是 Spring 框架的核心部分之一,它负责管理和维护应用程序中的对象(beans)
“Inversion of Control” 指的是将对象的创建、组装和依赖关系的管理权从应用程序代码转移到框架中

实例化 Bean

IOC 容器有两种主要的实现:

BeanFactory:

这是 Spring 最基本的容器,提供了最简单的 bean 容器功能。它延迟初始化 beans,即只有在请求时才会实际创建和初始化 bean。这对于资源消耗较大的 bean 非常有用。

ApplicationContext

这是 BeanFactory 的子接口,提供了更多的功能,如国际化支持、事件传播、AOP 功能等。ApplicationContext 在启动时会预先实例化和初始化 beans,以便在应用程序运行期间能够更快地访问和使用它们

容器概述

高水平概括
spring(1)_第1张图片

配置元数据

XML 配置文件:

<bean id="userService" class="com.example.UserService">
    <property name="userRepository" ref="userRepository" />
bean>

注解
使用 @Component 注解将一个类标记为一个 Spring bean:

@Component
public class UserService {
    // ...
}

Java 配置类:

@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService();
    }
}

实例化容器

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

<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="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <property name="itemDao" ref="itemDao"/>
        
    bean>

    

beans>

组合基于xml的配置元数据

模块化配置:
可以将不同的模块分开定义在不同的 XML 文件中。每个模块可以有自己的配置文件,其中定义了与该模块相关的 beans 和依赖关系。然后,在主配置文件中通过 元素引入这些模块的配置文件
所有位置路径都相对于执行导入的定义文件,

<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">

    <import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    前导斜杠会被忽略。然而,考虑到这些路径是相对的,最好不要使用斜杠
    <import resource="/resources/themeSource.xml"/>

    
beans>

Profile 切换:
你可以使用 Spring 的 Profile 功能,在不同的环境或条件下切换配置

<beans profile="development">
    
beans>

<beans profile="production">
    
beans>

使用容器

意味着在 Spring 框架中如何使用容器来管理和组织你的应用程序的组件

  1. 定义 Beans:
  2. 获取 Beans:
//1
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);

//2
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
//petStore是xml文件中的一个id
PetStoreService service = context.getBean("petStore", PetStoreService.class);
List<String> userList = service.getUsernameList();


//3
GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();
  1. 依赖注入:Spring 容器负责处理 beans 之间的依赖关系。你可以通过构造函数注入、setter 方法注入或字段注入等方式
  2. 生命周期管理:

bean的概述

spring(1)_第2张图片

命名bean

确保 bean 的名称是唯一的,以便在容器中准确引用

  1. xml
    Bean 的名称用于在**容器中引用、获取和识别 beans。**可以通过多种方式指定 bean 的名称
id一定是唯一的
<bean id="userService" class="com.example.UserService" />


name 属性可以指定多个名称,使用逗号或分号分隔。
<bean name="userBean,userService" class="com.example.UserService" />

  1. java:
    可以使用 @Component 注解来为 bean 分配一个默认名称,该名称是类名的小写字母开头的形式。

@Component
public class UserService {
    // ...
}


使用 Qualifier 注解:
@Autowired
@Qualifier("userService")
private UserService userService;


使用 Java 配置类:
@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService();
    }
}

别名的使用

  1. xml
<bean id="userService" class="com.example.UserService" />
<alias name="userService" alias="userManagementService" />

引用别名
<bean id="anotherBean" class="com.example.AnotherBean">
    <property name="userService" ref="userManagementService" />
bean>

2.AliasFor
这要求使用 @AliasFor 注解的类和 bean 必须具有相同的注解类型

@AliasFor("userService")
@Component("userManagementService")
public class UserManagementService {
    // ...
}

实例化bean

构造函数实例化

通过调用类的构造函数来完成的

 你可以使用 <constructor-arg> 元素来指定构造函数的参数值
<bean id="user" class="com.example.User">
   <constructor-arg value="John" />
   <constructor-arg value="Doe" />
bean>

静态工厂实例化

public class UserFactory {
   private UserFactory() {
       // private constructor to prevent direct instantiation
   }

   public static User createUser(String firstName, String lastName) {
       return new User(firstName, lastName);
   }
}

指定工厂类

<bean id="user" class="com.example.UserFactory" factory-method="createUser">
这是值
   <constructor-arg value="John" />
   <constructor-arg value="Doe" />
bean>

实例工厂方法

public class UserFactory {
    public User createUser(String firstName, String lastName) {
        return new User(firstName, lastName);
    }
}

指定

<bean id="userFactory" class="com.example.UserFactory" />

<bean id="user" factory-bean="userFactory" factory-method="createUser">
    <constructor-arg value="John" />
    <constructor-arg value="Doe" />
bean>

bean 在运行时的实际类型

Bean 类型和代理:用bean类型的和代理的类型
getClass() 方法:返回对象的实际运行时类,要注意,如果有代理存在,这个方法返回的可能是代理类的类型。
AopProxyUtils.ultimateTargetClass() 方法:这个方法会遍历代理链,找到最终的目标类。
目的:你可能需要了解对象的实际类型,特别是在处理代理、动态代理、AOP 等情况时。这有助于你更好地理解对象的行为和工作原理

依赖

依赖注入

Spring 框架的核心概念之一,它用于管理和注入对象之间的依赖关系。依赖注入的目的是降低组件之间的耦合度

  1. 构造函数
@Component
public class UserService {
    private UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // ...



package examples;

public class ExampleBean {

    // Fields omitted

    @ConstructorProperties({"years", "ultimateAnswer"})
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
   

使用xml

public class ThingOne {

    public ThingOne(ThingTwo thingTwo, ThingThree thingThree) {
        // ...
    }
}


}
<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>

也可以指定类型
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
bean>

指定index
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
bean>

指定名字
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
bean>
  1. Setter 方法注入
@Component
public class UserService {
    private UserRepository userRepository;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // ...
}
setter与constructor

因此对于**强制依赖项使用构造函数**,而对于**可选依赖项使用setter方法**或配置方法是一条很好的经验法则。**注意,在setter方法上使用@Required注释可以使属性成为required依赖项**
  1. 字段注入
@Component
public class UserService {

    @Autowired
    private UserRepository userRepository;

    // ...
}

你可能感兴趣的:(spring,java)