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

目录
  • 介绍
  • @Bean and @Configuration
  • AnnotationConfigApplicationContext实例化容器
  • 通过使用 register(Class...) 以编程方式构建容器
  • @ComponentScan启用组件扫描
  • Bean的依赖
  • 生命周期回调
  • Bean指定作用域
  • 自定义bean名称
  • Bean别名
  • Bean注入之间的依赖
  • @Import
  • @ImportResource
  • @PropertySource
  • 支持多个properties文件
  • ApplicationContext
  • MessageSource 国际化

介绍

我们将介绍如何在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容器的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java之Spring注解开发案例详解

    在Spring4之后,要使用注解开发,必须要保证aop的包导入了 使用注解需要导入context约束,增加注解的支持! <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&

  • 详解spring 配置的两种方式:JAVA配置和注解配置

    众所周知,spring自从3.0开始以后,就全面推荐使用配置的方式进行代码编写了,这种方式确实可以避免了之前一个项目里面一大堆XML的情况,毕竟XML的可读性实在不怎么样,而且一会写JAVA,一会写XML,确实还是蛮麻烦的 就目前来说spring的配置方式一般为两种:JAVA配置和注解配置.那么什么的是注解配置呢?什么是JAVA配置呢? //注解配置: @Service @Component @Repository @Controlle //JAVA配置 @Confirguration 相当于s

  • Java之Spring注解配置bean实例代码解析

    前面几篇均是使用xml配置bean,如果有上百个bean,这是不可想象的.故而,请使用注解配置bean !!! [1]注解类别 @Component : 基本注解, 标识了一个受 Spring(点击这里可以下载<Spring应用开发完全手册>) 管理的组件 @Repository : 标识持久层组件 @Service : 标识服务层(业务层)组件 @Controller : 标识表现层组件 Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件. 对于扫描到的组

  • Java Spring详解如何配置数据源注解开发以及整合Junit

    目录 Spring数据源的配置 数据源(连接池)的作用 数据源的开发步骤 手动创建数据源 Spring注解开发 Spring原始注解 Spring新注解 Spring整合Junit Spring集成Junit步骤 Spring数据源的配置 数据源(连接池)的作用 数据源(连接池)是提高程序性能如出现的 事先实例化数据源,初始化部分连接资源 使用连接资源时从数据源中获取 使用完毕后将连接资源归还给数据源 常见的数据源(连接池):DBCP.C3PO.BoneCP.Druid等 数据源的开发步骤 1.

  • Java Spring框架的注解式开发你了解吗

    目录 1.Spring框架的注解式开发 1.1开启注解扫描配置 1.2实例化相关注解 1.3控制对象的创建次数的注解 1.4注入相关的注解 1.5控制事务的相关注解 总结 1. Spring框架的注解式开发 # Spring框架的注解式(Annotation)开发 1. 注解式开发 定义:通过Spring框架提供的一系列注解来完成项目中快速开发 注解:Annotation是java中一种特殊的类 类似于interface 使用时:@注解类名(属性=参数) @Param(Mybatis中做参数绑定

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

    目录 介绍 @Bean and @Configuration AnnotationConfigApplicationContext实例化容器 通过使用 register(Class...) 以编程方式构建容器 @ComponentScan启用组件扫描 Bean的依赖 生命周期回调 Bean指定作用域 自定义bean名称 Bean别名 Bean注入之间的依赖 @Import @ImportResource @PropertySource 支持多个properties文件 ApplicationCo

  • 详解Java中自定义注解的使用

    目录 什么是注解 注解的注意事项 注解的本质 自定义注解使用 使用方式 1 使用方式 2 什么是注解 在早期的工作的时候 ,自定义注解写的比较多,可大多都只是因为 这样看起来 不会存在一堆代码耦合在一起的情况,所以使用了自定义注解,这样看起来清晰些, Annontation是Java5开始引入的新特征,中文名称叫注解. 它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类.方法.成员变量等)进行关联.为程序的元素(类.方法.成员变量)加上更直观.更明了的说

  • 详解Java进阶知识注解

    一.注解的概念 1.注解官方解释 注解 叫元数据,一种代码级别的说明,它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举在同一个层次,它可以声明在包.类.字段.局部变量.方法参数等的前面,用来对这些元素进行说明.注释. 注解的作用分类 编写文档:通过代码里表示的元数据生成文档[生成doc文档] 代码分析:通过代码里表示的元数据进行分析[使用反射] 编译检查:通过代码里表示的元数据让编译器能够实现基本的编译检查[Override] 注解按照运行机制分类 源码注解:注解只在源码中存在,编译成

  • 详解Java如何实现自定义注解

    目录 概念 作用 JDK中预定义的一些注解 注解生成文档案例 自定义注解 格式 本质 属性:接口中的抽象方法 元注解:用于描述注解的注解 在程序使用(解析)注解:获取注解中定义的属性值 案例:通过自定义注解定义一个简单的测试框架 总结 概念 概念:说明程序的.给计算机看的 注释:用文字描述程序的.给程序员看的 定义:注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次.它可以声明在包.类.字段.方法.局部变量.方法

  • 详解Java注解的实现与使用方法

    详解Java注解的实现与使用方法 Java注解是java5版本发布的,其作用就是节省配置文件,增强代码可读性.在如今各种框架及开发中非常常见,特此说明一下. 如何创建一个注解 每一个自定义的注解都由四个元注解组成,这四个元注解由java本身提供: @Target(ElementType.**) 这是一个枚举,它置顶是该自定义的注解使用的地方,像类.变量.方法等 @Retention(RetentionPolicy.**)作用是标明注解保存在什么级别,像在编译时.class文件中,vm运行中 @D

  • 详解Java注解知识点

    一.注解是什么 Java 注解用于为 Java 代码提供元数据,看完这句话也许你还是一脸懵逼,用人话说就是注解不直接影响你的代码执行,仅提供信息.接下我将从注解的定义.元注解.注解属性.自定义注解.注解解析JDK 提供的注解这几个方面再次了解注解(Annotation) 二.jdk支持的注解有哪些 2.1 三种常用的注解: @SuppressWarnings 该注解的作用是阻止编译器发出某些警告信息.它可以有以下参数: deprecation :过时的类或方法警告. unchecked:执行了未

  • 详解java注解相关知识

    定义 1.如果注解中有属性,那么必须给属性赋值. package com.lxc.Test; // 定义一个注解 public @interface Annotation { String name(); // 看似name像一个方法,实际上我们把name称为属性 } 使用上边注解: package com.lxc.Test; public class Test { @Annotation(name="lxc") public void test() { } } 2.如果注解中有属性,

  • 详解java代码中init method和destroy method的三种使用方式

    在java的实际开发过程中,我们可能常常需要使用到init method和destroy method,比如初始化一个对象(bean)后立即初始化(加载)一些数据,在销毁一个对象之前进行垃圾回收等等. 周末对这两个方法进行了一点学习和整理,倒也不是专门为了这两个方法,而是在巩固spring相关知识的时候提到了,然后感觉自己并不是很熟悉这个,便好好的了解一下. 根据特意的去了解后,发现实际上可以有三种方式来实现init method和destroy method. 要用这两个方法,自然先要知道这两

  • 详解Java分布式IP限流和防止恶意IP攻击方案

    前言 限流是分布式系统设计中经常提到的概念,在某些要求不严格的场景下,使用Guava RateLimiter就可以满足.但是Guava RateLimiter只能应用于单进程,多进程间协同控制便无能为力.本文介绍一种简单的处理方式,用于分布式环境下接口调用频次管控. 如何防止恶意IP攻击某些暴露的接口呢(比如某些场景下短信验证码服务)?本文介绍一种本地缓存和分布式缓存集成方式判断远程IP是否为恶意调用接口的IP. 分布式IP限流 思路是使用redis incr命令,完成一段时间内接口请求次数的统

  • 详解关于SpringBoot的外部化配置使用记录

    更新: 工作中突然想起来,关于Yaml的使用,并不属于Spring的范畴,是org.yaml.snakeyaml处理的.所以yaml的使用应该参考官方,不过貌似打不开... Spring利用snakeyaml将配置解析成PropertySource,然后写入到Environment,就能使用了 记录下使用SpringBoot配置时遇到的一些麻烦,虽然这种麻烦是因为知识匮乏导致的. 记录下避免一段时间后自己又给忘记了,以防万一. 如果放到博客里能帮助到遇到同样问题的同志,自是极好! SpringB

随机推荐