详解Java如何使用注解来配置Spring容器

 更新时间:2022年06月09日 11:37:35   作者:上海滩虎哥  
这篇文章我们将介绍如何在Java代码中使用注解来配置Spring容器,文中的示例代码讲解详细,对我们学习有一定参考价值,感兴趣的可以了解一下

介绍

我们将介绍如何在Java代码中使用注解来配置Spring容器。它包括:

  • Basic Concepts: @Bean and @Configuration。
  • Instantiating the Spring Container by Using 。
  • AnnotationConfigApplicationContext。
  • Using the @Bean Annotation。
  • Using the @Configuration annotation。
  • Composing Java-based Configurations。
  • Bean Definition Profiles。
  • PropertySource Abstraction。
  • Using @PropertySource。
  • Placeholder Resolution in Statements。

@Bean and @Configuration

@Bean注解用在一个方法上表示实例化、配置和初始化一个新对象,由Spring IoC容器管理。对于那些熟悉Spring的 XML配置的人来说,@Bean注解的作用与元素的作用相同。

用@Configuration来注解一个类,表明它的主要目的是作为一个bean定义的来源。此外,@Configuration类允许通过调用同一个类中的其他@Bean方法来定义Bean间的依赖关系。最简单的@Configuration类如下:

@Configuration
public class AppConfig {
    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    } 
    @Bean
    public OtherService otherService() {
        return new OtherService();
    }
}

AnnotationConfigApplicationContext实例化容器

与实例化

ClassPathXmlApplicationContext时使用Spring XML文件作为输入的方式相同,你可以在实例化AnnotationConfigApplicationContext时使用@Configuration类作为输入。这使得Spring容器的使用完全不需要XML,如下例子:

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
    MyService myService = ctx.getBean(MyService.class);
    myService.doStuff();
}

通过使用 register(Class...) 以编程方式构建容器

你可以通过使用无参数构造函数来实例化AnnotationConfigApplicationContext,然后使用 register() 方法来配置它。这种方法在以编程方式构建 AnnotationConfigApplicationContext 时特别有用。下面的例子展示了如何做到这一点。

public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.register(AppConfig.class, OtherConfig.class);
    ctx.register(AdditionalConfig.class);
    ctx.refresh();
    MyService myService = ctx.getBean(MyService.class);
    myService.doStuff();
}

@ComponentScan启用组件扫描

为了启用组件扫描,可以在@Configuration类做如下注释。

@Configuration
@ComponentScan(basePackages = "com.acme") 
public class AppConfig  {
    // ...
}

Bean的依赖

@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService(AccountRepository accountRepository) {
        return new TransferServiceImpl(accountRepository);
    }
}

生命周期回调

任何用@Bean注解定义的类都支持常规的生命周期回调,并且可以使用JSR-250的@PostConstruct和@PreDestroy注解。如果一个bean实现了InitializingBean、DisposableBean或Lifecycle,它们各自的方法将被容器调用。

public class BeanOne {

    public void init() {
        // initialization logic
    }
}
public class BeanTwo {

    public void cleanup() {
        // destruction logic
    }
}
@Configuration
public class AppConfig {

    @Bean(initMethod = "init")
    public BeanOne beanOne() {
        return new BeanOne();
    }
    @Bean(destroyMethod = "cleanup")
    public BeanTwo beanTwo() {
        return new BeanTwo();
    }
}

Bean指定作用域

Bean默认的作用域是singleton,更多Bean作用域可参考Bean作用域章节。

@Configuration
public class MyConfiguration {
    @Bean
    @Scope("prototype")
    public Encryptor encryptor() {
        // ...
    }
}

自定义bean名称

默认情况下,配置类使用@Bean方法的名称作为Bean的名称。可以通过name属性来自定义名称,如下:

@Configuration
public class AppConfig {
    @Bean("myThing")
    public Thing thing() {
        return new Thing();
    }
}

Bean别名

@Configuration
public class AppConfig {
    @Bean({"dataSource", "subsystemA-dataSource", "subsystemB-dataSource"})
    public DataSource dataSource() {
        // instantiate, configure and return DataSource bean...
    }
}

Bean注入之间的依赖

@Configuration
public class AppConfig {
    @Bean
    public BeanOne beanOne() {
        return new BeanOne(beanTwo());
    }
    @Bean
    public BeanTwo beanTwo() {
        return new BeanTwo();
    }
}

@Import

@Import注解表示要导入一个或多个@Configuration类。在导入的@Configuration类中声明的@Bean定义应该通过使用@Autowired注入来访问。

@Configuration
public class ConfigA {
    @Bean
    public A a() {
        return new A();
    }
}
@Configuration
@Import(ConfigA.class)
public class ConfigB {
    @Bean
    public B b() {
        return new B();
    }
}

现在,在实例化上下文时不需要同时指定ConfigA类和ConfigB类,而只需要明确提供ConfigB:

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);
    // now both beans A and B will be available...
    A a = ctx.getBean(A.class);
    B b = ctx.getBean(B.class);
}

@ImportResource

Spring提供了一个@ImportResource注解,用于从applicationContext.xml文件中加载bean到应用上下文中。

@Configuration
@ImportResource("classpath:/com/acme/properties-config.xml")
public class AppConfig {
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    @Bean
    public DataSource dataSource() {
        return new DriverManagerDataSource(url, username, password);
    }
}
<!-- properties-config.xml -->
<beans>
    <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>
</beans>

@PropertySource

我们将讨论如何使用@PropertySource来读取属性文件,并用@Value和Environment来显示值。

@PropertySource注解为向Spring的环境添加PropertySource提供了一种方便的声明性机制。要与@Configuration类一起使用。

假设我们从config.properties文件中读取数据库配置,并使用Environment将这些属性值设置为DataSourceConfig类。

@Configuration
@PropertySource("classpath:config.properties")
public class ProperySourceDemo implements InitializingBean {
    @Autowired
    Environment env;
    @Override
    public void afterPropertiesSet() throws Exception {
        setDatabaseConfig();
    }
    private void setDatabaseConfig() {
        DataSourceConfig config = new DataSourceConfig();
        config.setDriver(env.getProperty("jdbc.driver"));
        config.setUrl(env.getProperty("jdbc.url"));
        config.setUsername(env.getProperty("jdbc.username"));
        config.setPassword(env.getProperty("jdbc.password"));
        System.out.println(config.toString());
    }
}

支持多个properties文件

@Configuration
 @PropertySources({
  @PropertySource("classpath:config.properties"),
  @PropertySource("classpath:db.properties")
 })
 public class AppConfig {
  //...
 }

ApplicationContext

ApplicationContext实现了BeanFactory接口,并提供了如下功能:

  • 通过MessageSource接口,访问i18n风格的消息。
  • 通过ResourceLoader接口访问资源,如URL和文件。
  • 事件发布,即通过使用ApplicationEventPublisher接口,向实现ApplicationListener接口的bean发布。
  • 通过HierarchicalBeanFactory接口加载多个(分层的)上下文,让每个上下文专注于一个特定的层,例如一个应用程序的Web层。

MessageSource 国际化

ApplicationContext接口扩展了一个名为MessageSource的接口,因此,它提供了国际化("i18n")功能。Spring还提供了HierarchicalMessageSource接口,它可以分层次地解析消息。

account.name=TestAccount
@Configuration
public class AppConfig {
    @Bean
    public MessageSource messageSource() {
      ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
      messageSource.setBasename("config/messages");
      return messageSource;
    }
}
@Service
public class AccountService {
    @Autowired
    private MessageSource messageSource;
    
    public void someMsg() {
        messageSource.getMessage("account.name", null, Locale.ENGLISH);
        //todo
    }
}

以上就是详解Java如何使用注解来配置Spring容器的详细内容,更多关于Java注解配置Spring容器的资料请关注脚本之家其它相关文章!

相关文章

  • SpringCloud @RefreshScope刷新机制浅析

    SpringCloud @RefreshScope刷新机制浅析

    RefeshScope这个注解想必大家都用过,在微服务配置中心的场景下经常出现,他可以用来刷新Bean中的属性配置,那大家对他的实现原理了解吗?它为什么可以做到动态刷新呢
    2023-03-03
  • SpringBoot 策略模式实现切换上传文件模式

    SpringBoot 策略模式实现切换上传文件模式

    策略模式是指有一定行动内容的相对稳定的策略名称,这篇文章主要介绍了SpringBoot 策略模式 切换上传文件模式,需要的朋友可以参考下
    2023-11-11
  • IDEA查看所有的断点(Breakpoints)并关闭的方式

    IDEA查看所有的断点(Breakpoints)并关闭的方式

    我们在使用IDEA开发Java应用时,基本上都需要进行打断点的操作,这方便我们排查BUG,也方便我们查看设计的是否正确,不过有时候,我们不希望进入断点,所以我们需要快速关闭所有断点,故本文给大家介绍了IDEA查看所有的断点(Breakpoints)并关闭的方式
    2024-10-10
  • log4j2异步打印性能提升方式

    log4j2异步打印性能提升方式

    这篇文章主要介绍了log4j2异步打印性能提升方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • SpringCloud Eureka服务的基本配置和操作方法

    SpringCloud Eureka服务的基本配置和操作方法

    Eureka是Netflix开源的一个基于REST的服务治理框架,主要用于实现微服务架构中的服务注册与发现,Eureka是Netflix开源的服务发现框架,用于在分布式系统中实现服务的自动注册与发现,本文介绍SpringCloud Eureka服务的基本配置和操作方法,感兴趣的朋友一起看看吧
    2023-12-12
  • Mybatis中使用万能的Map传参实现

    Mybatis中使用万能的Map传参实现

    在编程中,有可能遇到我们的实体类或者数据库中表的字段或参数过多的情况,那这时候用Map传参是比较理想的选择,本文就详细的介绍一下如何使用,感兴趣的可以了解下
    2021-07-07
  • IDEA报java: java.lang.OutOfMemoryError: Java heap space错误解决办法

    IDEA报java: java.lang.OutOfMemoryError: Java heap space错误

    这篇文章主要给大家介绍了关于IDEA报java: java.lang.OutOfMemoryError: Java heap space错误的解决办法,文中将解决的办法介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • SpringBoot处理form-data表单接收对象数组的方法

    SpringBoot处理form-data表单接收对象数组的方法

    form-data则是一种更加灵活的编码方式,它可以处理二进制数据(如图片、文件等)以及文本数据,这篇文章主要介绍了SpringBoot处理form-data表单接收对象数组,需要的朋友可以参考下
    2023-11-11
  • Java数据结构之查找

    Java数据结构之查找

    本文主要介绍了Java数据结构中查找的相关知识。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • 常见JavaWeb安全问题和解决方案

    常见JavaWeb安全问题和解决方案

    这篇文章主要介绍了常见JavaWeb安全问题和解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03

最新评论