【Spring】Bean加载方式

Bean加载方式

本文适合已经有了Spring基础的读者来阅读,如果你对Spring有一定了解但又没那么了解,或者你想要去了解SpringBoot的自动配置原理,读完这篇文章之后一定能对你有所帮助

1 环境准备

按照以下步骤搭建一个Demo,方便后续演示使用:

1)新建一个maven项目,在pom文件中导入spring的依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.9</version>
</dependency>

2)新建一个com.itheima.bean包,这个包用来存放一些后续演示中会使用的Bean。在包中创建以下类:

public class Cat {
   
}

public class Dog {
   
}

public class Mouse {
   
}

3)在com.itheima.bean中新建一个service包,包中创建以下接口:

public interface BookSerivce {
   
    void check();
}

4)在service包中创建一个impl包,在包中创建以下类

public class BookServiceImpl1 implements BookSerivce {
   
    @Override
    public void check() {
   
        System.out.println("book service 1..");
    }
}

public class BookServiceImpl2 implements BookSerivce {
   
    @Override
    public void check() {
   
        System.out.println("book service 2....");
    }
}

public class BookServiceImpl3 implements BookSerivce {
   
    @Override
    public void check() {
   
        System.out.println("book service 3......");
    }
}

public class BookServiceImpl4 implements BookSerivce {
   
    @Override
    public void check() {
   
        System.out.println("book service 4........");
    }
}

这样基础环境就搭建好了,整体结构如下:

在这里插入图片描述


2 Bean加载方式之XML方式

2.1 配置自定义Bean

在resources目录下新建一个名为applicationContext1.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>

如果希望在spring容器中加载某个类的Bean,那么只需要在标签中添加一个标签,并按照以下格式配置类的信息即可:

<!--定义一个id为cat的Bean,Bean的类型为Cat-->
<bean id="cat" class="com.itheima.bean.Cat"/>

如果我们希望使用这个Bean,只需要从容器获取即可,具体如下:

在com.itheima包下创建一个app包,这个包专门用来演示获取Bean,在app包下新建一个类,内容如下:

public class App1 {
   
    public static void main(String[] args) {
   
        //获取容器对象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext1.xml");
        //获取Bean
        Object cat = ctx.getBean("cat");
        System.out.println(cat);
    }
}

我们在xml中声明Bean时,也可以不指定类型,例如:

<!--定义一个id为cat的Bean,Bean的类型为Cat-->
<bean id="cat" class="com.itheima.bean.Cat"/>

<!--创建一个Dog的Bean,不指定id-->
<bean class="com.itheima.bean.Dog"/>

那么我们在获取Bean的时候就只能根据类型去获取

public class App1 {
   
    public static void main(String[] args) {
   
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationCOntext1.xml");
        Object cat = ctx.getBean("cat");
        System.out.println(cat);
        //获取Dog类型的Bean
        Dog dog = ctx.getBean(Dog.class);        
        System.out.println(dog);
    }
}

如果spring容器中存在两个以上Dog类型的Bean,我们按类型获取就会出现异常,这时就只能给不同的DogBean定义id然后根据id获取了

我们还可以通过以下方法获取容器中我们手动添加的所有Bean的定义信息

public class App1 {
   
    public static void main(String[] args) {
   
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationCOntext1.xml");
//        Object cat = ctx.getBean("cat");
//        System.out.println(cat);
//        Dog dog = ctx.getBean(Dog.class);
//        System.out.println(dog);
        //获取所有Bean的DefinitionName,即定义名
        String[] names = ctx.getBeanDefinitionNames();
        //循环打印
        for (String name : names) {
   
            System.out.println(name);
        }
    }
}

打印信息如下:

在这里插入图片描述

当我们在定义Bean的时候,如果指定了id,那么Bean的DefinitionName就是我们指定的id,如果我们没有指定id,那么DefinitionName默认就是类的全路径名#数字编号,如果该类型的Bean是容器中第一个,那个数字编号就为0,第二个则为1,以此类推。

我们通过id获取Bean的方式实际上是通过DefinitionName来获取Bean,也就是说,如果我们希望获取Dog的Bean,也可以这样写:

public class App1 {
   
    public static void main(String[] args) {
   
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationCOntext1.xml");
        //通过Bean的默认定义名来获取Bean
        Object cat = ctx.getBean("com.itheima.bean.Dog#0");
        System.out.println(cat);
    }
}

虽然我并不认为有人会这样去获取

2.2 配置第三方Bean

除了配置我们自己定义的Bean之外,也可以在xml中配置一些第三方的Bean,例如数据库连接池等等,演示如下:

1)在pom文件中引入druid的依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>

2)在xml文件中配置druid的Bean(这里只是演示一下,数据源啥的就不配了)

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>

3)从容器中进行获取:

public class App1 {
   
    public static void main(String[] args) {
   
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationCOntext1.xml");
//        Object cat = ctx.getBean("cat");
//        System.out.println(cat);
//        Dog dog = ctx.getBean(Dog.class);
//        System.out.println(dog);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
   
            System.out.println(name);
        }
    }
}

打印结果如下:

在这里插入图片描述

如果我们没有指定id,也会按照类的全路径名#数字编号的格式为第三方Bean配置一个默认的DefinitionName


3 Bean加载方式之注解方式

3.1 配置自定义Bean

注解方式是为了简化xml方式的,如果我们需要将一个类加载到spring容器中,只需要在类上打上一个注解即可:

//将Cat类的一个Bean加载到容器中,Bean的名称为tom
@Component("tom")
public class Cat {
   

}

@Component有三个衍生注解,分别是@Controller@Service@Repository,分别对应着Controller层,Service层和Dao层的Bean,这三个注解作用和@Component基本一致,更多的是起一个区分和标志作用

除此之外,我们还需要在xml中配置spring的包扫描,用来扫描对应包下的注解,并将包中打上注解的类加载到spring容器中

新建一个配置文件,名为applicationContext2.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
    ">

    <!--配置包扫描-->
    <context:component-scan base-package="com.itheima.bean"/>
</beans>

如果要获取容器中的Bean,只需要采用相同的方式即可,这里为了不干扰,我们在app包下新建一个类来演示

public class App2 {
   
    public static void main(String[] args) {
   
        ApplicationContext ctx = new
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值