Spring之路(10)--详解Spring中bean命名机制

简介: 本文目录1. 概述2. xml配置中bean命名3. 注解配置中bean命名4. JavaConfig配置中bean命名5. 总结

1. 概述

上一篇已经对bean命名的重要性进行了说明,本篇主要讲解下bean命名的具体实现方式,同时还会实验下如果出现重复命名,Spring会如何处理。


2. xml配置中bean命名

首先有一个歌手类:


package org.maoge.xmlbeandetail;

public class Singer {

private String name;

public void sing() {

 System.out.println("歌手[" + name + "]开唱啦,快挥舞起你手中的荧光棒吧");

}

public String getName() {

 return name;

}

public void setName(String name) {

 this.name = name;

}

}


在xml中对bean进行正常命名,给两个bean分别命名为zhoujielun、linjunjie。


<?xml version="1.0" encoding="UTF-8"?><!-- spring.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

       http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="zhoujielun" class="org.maoge.xmlbeandetail.Singer">

 <property name="name" value="周杰伦"></property>

</bean>

<bean id="linjunjie" class="org.maoge.xmlbeandetail.Singer">

 <property name="name" value="林俊杰"></property>

</bean>

</beans>


在主类中,首先获取容器,然后通过命名获取容器中的bean:


package org.maoge.xmlbeandetail;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

public static void main(String[] args) {

 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(

   "/org/maoge/xmlbeandetail/spring.xml");

 // 杰伦来了

 Singer zhoujielun = context.getBean("zhoujielun", Singer.class);

 zhoujielun.sing();

 // 俊杰来了

 Singer linjunjie = context.getBean("linjunjie", Singer.class);

 linjunjie.sing();

}

}


执行结果:


歌手[周杰伦]开唱啦,快挥舞起你手中的荧光棒吧

歌手[林俊杰]开唱啦,快挥舞起你手中的荧光棒吧


此时如果修改spring.xml文件,在其中命名两个重名的bean,如下:


<?xml version="1.0" encoding="UTF-8"?><!-- spring.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

       http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="zhoujielun" class="org.maoge.xmlbeandetail.Singer">

 <property name="name" value="周杰伦"></property>

</bean>

<bean id="zhoujielun" class="org.maoge.xmlbeandetail.Singer">

 <property name="name" value="林俊杰"></property>

</bean>

</beans>


执行Main.java主类时,控制台报错,提示名称为zhoujielun的bean已经存在了,所以在同一xml配置中,Spring是不允许出现同名bean的。


Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException:

Configuration problem: Bean name 'zhoujielun' is already used in this <beans> element


3. 注解配置中bean命名

可以使用@Component("beanName")将类生成的bean命名为beanName,如果直接使用@Component,则采用类名首字母小写的形式作为生成bean的名称。


例如:


@Component("zhoujielun")//生成bean的名称为zhoujielun

public class Singer {

}


@Component//生成bean的名称为singer,即类名首字母小写

public class Singer {

}


4. JavaConfig配置中bean命名

使用@Bean标注到方法上,方法的名称即为生成bean的名称,如下:


package org.maoge.javaconfigbean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class BeanConfiguration {

@Bean//生成bean名称为zhoujielun

public Singer zhoujielun() {

 Singer singer = new Singer();

 singer.setName("周杰伦");

 return singer;

}

@Bean//生成bean名称为linjunjie

public Singer linjunjie() {

 Singer singer = new Singer();

 singer.setName("林俊杰");

 return singer;

}

}


运行主类:


package org.maoge.javaconfigbean;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class JavaConfigContainerDemo {

public static void main(String[] args) {

 AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(BeanConfiguration.class);

 Singer zhoujielun=(Singer) context.getBean("zhoujielun");

 zhoujielun.sing();

 Singer linjunjie=(Singer) context.getBean("linjunjie");

 linjunjie.sing();

}

}


正常输出:


歌手[周杰伦]开唱啦,快挥舞起你手中的荧光棒吧

歌手[林俊杰]开唱啦,快挥舞起你手中的荧光棒吧

1

2

此时,如果我们配置两个同名的bean,强制将两个bean都命名为zhoujielun,如下:


package org.maoge.javaconfigbean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class BeanConfiguration {

@Bean(name= {"zhoujielun"})//强制将bean命名为zhoujielun

public Singer zhoujielun() {

 Singer singer = new Singer();

 singer.setName("周杰伦");

 return singer;

}

@Bean(name= {"zhoujielun"})//强制将bean命名为zhoujielun

public Singer linjunjie() {

 Singer singer = new Singer();

 singer.setName("林俊杰");

 return singer;

}

}


再次运行主类,控制台输出如下:


歌手[周杰伦]开唱啦,快挥舞起你手中的荧光棒吧

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'linjunjie' available

  at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:682)

  at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1218)

  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)

  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)

  at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1082)

  at org.maoge.javaconfigbean.JavaConfigContainerDemo.main(JavaConfigContainerDemo.java:8)


首先我们发现如果@Configuration配置类中有重名的bean,第一个会覆盖后面的,也就是说第一个生效。后面报错是因为没有名字为linjunjie的bean了,因为第二个bean已经通过@Bean(name= {"zhoujielun"})强制命名为zhoujielun了。


5. 总结

在正常开发过程,还是要遵循每个bean名称都要有唯一名称的原则,即便同时采用了多种配置方式,也要为每个bean采用单独名称。


毕竟,虽然配置方式不同,但是生成的bean都是在Spring容器中一样管理的。

相关文章
|
27天前
|
XML 安全 Java
|
4天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
4天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
12天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
57 14
|
9天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
42 6
|
11天前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
62 3
|
25天前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
32 1
|
28天前
|
缓存 Java 数据库连接
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
45 4
|
6月前
|
Java 开发者 Spring
解析Spring中Bean的生命周期
解析Spring中Bean的生命周期
62 2
|
6月前
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
74 0