0


详细分析Spring中的@Configuration注解基本知识(附Demo)

目录

前言

Java的基本知识推荐阅读:

  1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
  2. Spring框架从入门到学精(全)

拓展应用补充阅读:@Configuration注解使用

1. 基本知识

在Java和Spring框架中,

@Configuration

注解用于定义配置类,这些类可以替代传统的XML配置文件

  • 是Spring的一部分,用于创建和管理bean,提供了更灵活和强大的配置机制
  • 配置类包含了一个或多个@Bean方法,这些方法返回要在Spring容器中管理的bean

基本示例如下:

AppConfig类被标注为一个配置类,并且定义了一个myService方法,该方法返回一个MyService实例

importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassAppConfig{@BeanpublicMyServicemyService(){returnnewMyServiceImpl();}}

自动装配:
配置类中的bean可以自动装配到其他bean中

@ConfigurationpublicclassAnotherConfig{privatefinalMyService myService;@AutowiredpublicAnotherConfig(MyService myService){this.myService = myService;}@BeanpublicAnotherServiceanotherService(){returnnewAnotherServiceImpl(myService);}}

2. 详细分析

注解继承与组合:
@Configuration类可以使用其他Spring注解,如@ComponentScan和@Import,来扫描组件或导入其他配置类

@Configuration@ComponentScan(basePackages ="com.example")publicclassAppConfig{// Bean定义}@Configuration@Import(AppConfig.class)publicclassMainConfig{// 主要配置}

代理机制:
@Configuration类在Spring容器启动时会通过CGLIB动态代理机制生成代理类,以确保@Bean方法只被调用一次,从而保证单例bean的行为

@ConfigurationpublicclassConfigClass{@BeanpublicMyBeanmyBean(){returnnewMyBean();}@BeanpublicAnotherBeananotherBean(){// myBean() 方法将返回相同的实例,而不会创建新实例returnnewAnotherBean(myBean());}}

条件化配置:
使用@Conditional注解,可以根据某些条件来决定是否创建某个bean

@ConfigurationpublicclassConditionalConfig{@Bean@Conditional(MyCondition.class)publicMyBeanconditionalBean(){returnnewMyBean();}}

环境和属性配置:
使用@PropertySource和@Value注解可以将外部属性文件中的值注入到配置类中

@Configuration@PropertySource("classpath:application.properties")publicclassPropertyConfig{@Value("${my.property}")privateString myProperty;@BeanpublicPropertyBeanpropertyBean(){returnnewPropertyBean(myProperty);}}

3. Demo

3.1 简单Bean配置

总体完整的Demo如下:

// AppConfig.javapackagecom.example.demo;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassAppConfig{@BeanpublicMyServicemyService(){returnnewMyService();}@BeanpublicMyControllermyController(){returnnewMyController(myService());}}// MyService.javapackagecom.example.demo;publicclassMyService{publicStringsayHello(){return"Hello, World!";}}// MyController.javapackagecom.example.demo;publicclassMyController{privatefinalMyService myService;publicMyController(MyService myService){this.myService = myService;}publicStringgreet(){return myService.sayHello();}}// AppTest.javapackagecom.example.demo;importorg.springframework.context.ApplicationContext;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;publicclassAppTest{publicstaticvoidmain(String[] args){ApplicationContext context =newAnnotationConfigApplicationContext(AppConfig.class);MyController controller = context.getBean(MyController.class);System.out.println(controller.greet());// 输出: Hello, World!}}

最终执行结果如下:

在这里插入图片描述

3.2 属性配置

// AppConfig.javapackagecom.example.demo;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.PropertySource;@Configuration@PropertySource("classpath:application.properties")publicclassAppConfig{@Value("${app.message}")privateString message;@BeanpublicMessageServicemessageService(){returnnewMessageService(message);}}// MessageService.javapackagecom.example.demo;publicclassMessageService{privatefinalString message;publicMessageService(String message){this.message = message;}publicStringgetMessage(){return message;}}// AppTest.javapackagecom.example.demo;importorg.springframework.context.ApplicationContext;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;publicclassAppTest{publicstaticvoidmain(String[] args){ApplicationContext context =newAnnotationConfigApplicationContext(AppConfig.class);MessageService service = context.getBean(MessageService.class);System.out.println(service.getMessage());// 输出配置文件中的app.message值}}// application.properties
app.message=Hello from properties!

截图如下:

在这里插入图片描述

3.3 多条件配置

// AppConfig.javapackagecom.example.demo;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Conditional;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassAppConfig{@Bean@Conditional(MyCondition.class)publicConditionalServiceconditionalService(){returnnewConditionalService();}}// MyCondition.javapackagecom.example.demo;importorg.springframework.context.annotation.Condition;importorg.springframework.context.annotation.ConditionContext;importorg.springframework.core.type.AnnotatedTypeMetadata;publicclassMyConditionimplementsCondition{@Overridepublicbooleanmatches(ConditionContext context,AnnotatedTypeMetadata metadata){// 返回true时才会创建ConditionalService beanreturntrue;}}// ConditionalService.javapackagecom.example.demo;publicclassConditionalService{publicStringgetMessage(){return"Conditional Service is active!";}}// AppTest.javapackagecom.example.demo;importorg.springframework.context.ApplicationContext;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;publicclassAppTest{publicstaticvoidmain(String[] args){ApplicationContext context =newAnnotationConfigApplicationContext(AppConfig.class);if(context.containsBean("conditionalService")){ConditionalService service = context.getBean(ConditionalService.class);System.out.println(service.getMessage());// 输出: Conditional Service is active!}else{System.out.println("Conditional Service is not active");}}}

截图如下:

在这里插入图片描述

4. 实战拓展

对于这个@Configuration注解,往往会配合proxyBeanMethods一起使用

  • proxyBeanMethods = true(默认行为):表示Spring会为配置类生成一个CGLIB代理对象,以确保每个@Bean方法只会被调用一次,并且返回相同的实例(单例模式) 这种方式可以确保@Bean方法间的依赖能够正确处理
  • proxyBeanMethods = false:表示Spring不会为配置类生成代理对象,每次调用@Bean方法时都会返回一个新的实例 这种方式可以减少CGLIB代理的开销,适用于@Bean方法之间没有依赖关系的场景

Demo如下:

@Configuration(proxyBeanMethods = false)

是一个Spring的注解,用于标识一个类是配置类,同时指定该配置类中@Bean方法的代理行为
方法每次调用都会返回一个新的 DeptDataPermissionRuleCustomizer 实例

@Configuration(proxyBeanMethods =false)publicclassDataPermissionConfiguration{@BeanpublicDeptDataPermissionRuleCustomizersysDeptDataPermissionRuleCustomizer(){return rule ->{// dept
            rule.addDeptColumn(AdminUserDO.class);
            rule.addDeptColumn(DeptDO.class,"id");
            rule.addDeptColumn(AppointmentCommissionDO.class,"dept_id");// user
            rule.addUserColumn(AdminUserDO.class,"id");
            rule.addUserColumn(AppointmentCommissionDO.class,"user_id");};}}
标签: spring java 后端

本文转载自: https://blog.csdn.net/weixin_47872288/article/details/140247278
版权归原作者 码农研究僧 所有, 如有侵权,请联系我们删除。

“详细分析Spring中的@Configuration注解基本知识(附Demo)”的评论:

还没有评论