Spring容器创建Bean的三种方式

我们知道,Spring是通过IOC容器实现对对象(也就是Bean)的管理的。IOC容器通过读取配置元数据来获得要实例化、配置、组装对象的元信息,以便实现针对用户程序中对象的统一管理。
image
IOC容器可以使用的元数据配置信息有三种,分别是基于XML的配置基于注解的配置基于Java的配置,下面分别对三种配置进行介绍。

一、基于XML的容器配置

  1. 新建由IOC容器管理的实体类UserService
package com.bx.spring.service;

public class UserService {
    public void print() {
        System.out.println("UserService......");
    }
}
  1. resources目录下新建applicationContext.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">

    <bean id="userService" class="com.bx.spring.service.UserService"></bean>
</beans>
  1. 获取userService对象
package com.bx.spring;

import com.bx.spring.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class Main {
    public static void main(String[] args) {
        //扫描路径
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取bean
        UserService userService = (UserService) context.getBean("userService");
        userService.print();
    }
}

二、基于注解的容器配置

  1. 新建被注入的类Person以及待注入的类Company
package com.bx.spring.eneity;

public class Person {
    private String name = "bob";
    private int age = 18;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.bx.spring.eneity;

import org.springframework.beans.factory.annotation.Autowired;


public class Company {

    private Person person;

    public Person getPerson() {
        return person;
    }
    //使用@Autowired注解将person注入company中
    @Autowired
    public Company(Person person) {
        this.person = person;
    }

}
  1. 在resources目录下新建applicationContext2.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!--    注解配置启用-->
    <context:annotation-config/>

    <bean id="person" class="com.bx.spring.eneity.Person">

    </bean>

    <bean id="company" class="com.bx.spring.eneity.Company">

    </bean>
</beans>
  1. 运行主类,获取company实体
package com.bx.spring;

import com.bx.spring.eneity.Company;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        //扫描路径
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
        //获取bean
        Company company = (Company) context.getBean("company");

        System.out.println(company.getPerson().toString());

    }
}

以上采用注解注入依赖的方式仍然需要在xml配置文件中通过<bean>标签定义bean的元信息。实际上,可以进一步对xml进行简化,可以通过以下两步骤进行简化。

  • 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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!--    注解配置启用-->
    <context:annotation-config/>
    <!--配置包扫描的路径,不再需要下面复杂的bean定义-->
    <context:component-scan base-package="com.bx.spring"></context:component-scan>
<!--    <bean id="person" class="com.bx.spring.eneity.Person">-->
<!--    </bean>-->

<!--    <bean id="company" class="com.bx.spring.eneity.Company">-->
<!--    </bean>-->
</beans>
  • 通过注解标记类为bean
package com.bx.spring.eneity;

import org.springframework.stereotype.Component;

@Component
public class Person {
    private String name = "bob";
    private int age = 18;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.bx.spring.eneity;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Component
public class Company {

    private Person person;

    public Person getPerson() {
        return person;
    }

    @Autowired
    public Company(Person person) {
        this.person = person;
    }
}

@Component注解告诉Spring这些类是需要注入的,前提是在xml中配置了包扫描路径。@Autowired注解将Person依赖注入到Company中。

三、基于Java类的容器配置

基于Java类的容器配置,无需XML配置文件,因而显得更加简洁。通常用@Configuration来注解一个类,表明它作为Bean定义的来源,可以理解为<beans>标签;用@Bean注解对Bean进行定义,可以理解为<bean>标签。

  1. 新建包config,包下新建配置类AppConfig。
//AppConfig.java
package com.bx.spring.config;

import com.bx.spring.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public UserService myService() {
        return new UserService();
    }
}
//UserService.java
package com.bx.spring.service;

public class UserService {
    public void print() {
        System.out.println("UserService......");
    }
}

2.运行主类

package com.bx.spring;

import com.bx.spring.config.AppConfig;
import com.bx.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


public class Main {
    public static void main(String[] args) {
        //扫描路径
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        //获取bean
        UserService userService = (UserService) context.getBean(UserService.class);

        System.out.println(userService);

    }

}

参考文档:
https://springdoc.cn/spring/core.html#beans-autowired-annotation
https://juejin.cn/post/7058885685851193380

posted @ 2023-12-27 09:28  梦醒时风  阅读(213)  评论(0)    收藏  举报