欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > 【IoCDI】_方法注解@Bean

【IoCDI】_方法注解@Bean

2025/5/3 13:33:24 来源:https://blog.csdn.net/m0_63299495/article/details/145431041  浏览:    关键词:【IoCDI】_方法注解@Bean

目录

1. 类注解的使用局限

2. 仅使用@Bean注解

3. 五大注解配合使用@Bean

3.1 使用方式1:getBean传参Bean类型

3.2 使用方式2:getBean传参Bean名称

3.3 使用方式3:getBean传参Bean名称+类型


在上文中,已经介绍了五大类注解及getBean方法的使用,详见下文:

【Ioc&DI】_存储Bean的五大类注解及getBean的使用-CSDN博客文章浏览阅读607次,点赞6次,收藏18次。(1) 类注解:@Controller、@Service、@Repository、@Component、@Configuration;在系统中,对于非Controller层、非Service层和非Dao层的其他bean,使用@Component注解实现存储;在上文实现IoC基本存取功能的两个注解中,要把某个对象交给IOC容器管理,需要在类上添加⼀个@Component注解。(@Controller、@Service、@Repository与三层架构分别对应)https://blog.csdn.net/m0_63299495/article/details/145421932?sharetype=blogdetail&sharerId=145421932&sharerefer=PC&sharesource=m0_63299495&spm=1011.2480.3001.8118https://blog.csdn.net/m0_63299495/article/details/145421932?sharetype=blogdetail&sharerId=145421932&sharerefer=PC&sharesource=m0_63299495&spm=1011.2480.3001.8118https://blog.csdn.net/m0_63299495/article/details/145421932?sharetype=blogdetail&sharerId=145421932&sharerefer=PC&sharesource=m0_63299495&spm=1011.2480.3001.8118已经了解到:

Spring提供的注解可分为两大类:

1、类注解:@Controller、@Service、@Repository、@Component、@Configuration;

2、方法注解:@Bean;

基于已经了解的五大类注解的相关知识,现介绍方法注解@Bean。

1. 类注解的使用局限

在上文(见链接)中,已经提到,五大注解只能加在类上。

除此之外,类注解还有2个局限性:

1、五大注解只能加在类上,并且只能加在自己的代码上

如果引入了一个第三方的Jar包也希望交给Spring管理,则无法加五大注解。

2、通过类注解修饰的bean在Spring容器中仅存储一份

对于一个类,定义多个对象(如数据库操作定义多个数据源)时,类注解也是无法发挥作用的。

注:对于第2条,可以进行测试:

在Config包下创建一个UserConfig类,在启动类中进行测试:

package com.example.iocdemo1;import com.example.iocdemo1.Config.UserConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class IoCDemo1Application {public static void main(String[] args) {ApplicationContext context=SpringApplication.run(IoCDemo1Application.class, args);UserConfig config1 = context.getBean(UserConfig.class);System.out.println("config1: "+config1);UserConfig config2=context.getBean(UserConfig.class);System.out.println("config2: "+config2);System.out.println("config1 == config2? "+(config1 == config2));}
}

启动项目查看日志:

可见config1与config2地址相同,本质上是一个对象。可见使用类注解修饰的类,在容器当中仅存储了一份,无论使用getBean取出多少次,取出的都是同一个bean;

2. 仅使用@Bean注解

在Config包下创建一个UserInfo类:

package com.example.iocdemo1.Config;
import lombok.Data;
@Data
public class UserInfo {private int id;private String name;private int age;
}

在同个包下再创建一个BeanConfig类:

package com.example.iocdemo1.Config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;public class BeanConfig {@Beanpublic UserInfo userInfo(){UserInfo userInfo1=new UserInfo();userInfo1.setId(1);userInfo1.setName("zhangsan");userInfo1.setAge(20);return userInfo1;}@Beanpublic UserInfo userInfo2(){UserInfo userInfo2=new UserInfo();userInfo2.setId(2);userInfo2.setName("lisi");userInfo2.setAge(21);return userInfo2;}
}

在运行类中尝试获取UserInfo:

package com.example.iocdemo1;import com.example.iocdemo1.Config.UserInfo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class IoCDemo1Application {public static void main(String[] args) {ApplicationContext context=SpringApplication.run(IoCDemo1Application.class, args);UserInfo userInfo = context.getBean(UserInfo.class);System.out.println(userInfo);}
}

运行程序,报错如下:

表示未找到类型为UserInfo.class的bean。

3. 五大注解配合使用@Bean

3.1 使用方式1:getBean传参Bean类型

在2.1部分,已完成了在BeanConfig类的方法前使用@Bean注解。

启动程序发现,程序抛异常:NoSuchBeanDefinitionException,这与Spring的扫描机制有关。

Spring通过扫描注解来明确需要管理的bean,但扫描并不全盘扫描方法注解。

对于方法注解@Bean,需要配合使用五大注解才能将对象正确存储到容器中

在BeanConfig类前增加@Configuration注解:

package com.example.iocdemo1.Config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfo(){UserInfo userInfo1=new UserInfo();userInfo1.setId(1);userInfo1.setName("zhangsan");userInfo1.setAge(20);return userInfo1;}@Beanpublic UserInfo userInfo2(){UserInfo userInfo2=new UserInfo();userInfo2.setId(2);userInfo2.setName("lisi");userInfo2.setAge(21);return userInfo2;}
}

保持其他类程序不变,重新启动程序:

启动程序发现,程序抛异常:NoSuchBeanDefinitionException,表示当前扫描到两个bean,一个bean名为userInfo,一个bean名为userInfo2;

再次对应启动类相关代码,当前使用方式中,Spring无法识别bean的原因在于:

以传参为Bean类型调用getBean时,若一个类型存在多个Bean时,就会使得Spring无法确定到底要使用哪个类

注:关于不同注解方式下的bean的名称:

使用@Bean注解时,bean的名称是方法名

使用五大注解时,bean的名称是类名的小驼峰表示法,且当类名前两个字母均为大写时,bean名即类名

3.2 使用方式2:getBean传参Bean名称

针对某类型存在多个Bean时,使用方式1存在的问题,可采用第2种使用方式。

给getBean方法传参Bean的名称,修改启动类程序如下:

package com.example.iocdemo1;import com.example.iocdemo1.Config.UserInfo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class IoCDemo1Application {public static void main(String[] args) {ApplicationContext context=SpringApplication.run(IoCDemo1Application.class, args);UserInfo userInfo1 = (UserInfo) context.getBean("userInfo");System.out.println(userInfo1);UserInfo userInfo2 = (UserInfo) context.getBean("userInfo2");System.out.println(userInfo2);}
}

重新启动程序:

注:对于给getBean方法传参Bean的名称(方式2)需要强制类型转换

3.3 使用方式3:getBean传参Bean名称+类型

对某类型存在多个Bean,使用方式1存在的问题,除第2种使用方式外,可采用第3种使用方式。

给getBean方法传参Bean的名称+类型,修改启动类程序如下:

package com.example.iocdemo1;import com.example.iocdemo1.Config.UserInfo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class IoCDemo1Application {public static void main(String[] args) {ApplicationContext context=SpringApplication.run(IoCDemo1Application.class, args);UserInfo userInfo1=context.getBean("userInfo",UserInfo.class);System.out.println(userInfo1);UserInfo userInfo2=context.getBean("userInfo2", UserInfo.class);System.out.println(userInfo2);}
}

重新启动程序:

注:相较于给getBean方法传参Bean的名称(方式2),getBean方法传参Bean的名称+类型(方式3)无需强制类型转换

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词