前言

在Spring框架中,有两种对容器的配置和启动方式,一种是基于XML文档的配置方式,一种则是“零配置”,即Java Based Configuration。

而在零配置中,最常见的就是单独使用@Component(及其等效注解@Controller@Repository@Service),或者共同使用@Configuration@Bean注解,这里将全部介绍。同时也会介绍几乎所有常见的注解配置

@Component

该注解是配置Bean的最基本注解,当该注解修饰一个类时,在初始化容器并扫描后,会进行基本的Bean配置。

@Component
public class Person {
	private Axe axe;
	public void setAxe(Axe axe) {
		this.axe = axe;
	}
}

这直接就相当于在容器中配置了一个id为person的bean,当然,默认id是类的首字母小写,也可以这样自定义名称:

@Component("person")

至于@Repository@Controller@Service都是@Component的变体,作用完全一致,只是为了便于区分常常用于修饰不同的类型,分别是数据层bean,控制层bean,服务层bean。

@Scope

该注解用于指定被修饰的bean的作用域,Spring中的bean一共有6种作用域:

  1. singleton单例模式,只生成一个实例
  2. prototype原型模式,每次获取bean时都会生成一个实例
  3. request,对于每一个HTTP请求都会生成一个实例
  4. session,对于每一次HTTP会话都会生成一个实例
  5. application,对于整个web应用,该bean只生成一个实例
  6. websocket,对于整个WebSocket通信,该bean只生成一个实例
    使用方法就是直接将对应的作用域名称作为value值传给@Scope
@Scope("singleton")

@Resource、@Value

这两个注解用于配置依赖项,前者用于注入容器中的bean,后者用于直接注入值。

这里注意@Resource这个注解默认时byName的,可以通过指定name属性来指定要注入的bean的id是什么,当然也可通过指定type的方式调整为byType注入

@PostConstuct、@PreDestroy

这两个注解用于生命周期回调

@Component
public class Person {
	// ...
	// ...
	@PostConstuct
	public void init() {
		System.out.println("Doing init method...");
	}

	@PerDestroy
	public void destroy() {
		System.out.println("Doing destroy method...");
	}
}

@Bean

该注解一般需要配合@Configuration走CGLIB代理才能发挥出更好的作用。
实际上该注解是将该注解修饰的函数的返回值作为bean注册到容器中。

@Configuration
public class MyBean {

    @Bean(value = "wood", initMethod = "init")
    public Axe getWoodAxe() {
        return new WoodAxe();
    }


    @Bean("axeMan")
    public Person getAxeMan(Axe axe) {
        return axe::chop;
    }

这里注意,当我们使用@Bean注解时,可以通过之前的方式指定生命周期回调,但是也可通过@Bean自带的属性来指定,但是指定的必须是返回值类中有的函数(如果返回值为一个接口,接口中必须有相关的函数)

其次,@Bean注解修饰的函数可以带任意数量的形参,形参会自动执行byType的自动注入,因此需要注意当检测到多个可匹配的类时会报错。

同时,当指定bean的生命周期时,仍然是使用上述@Scope注解

并且,可以使用name属性指定该bean的名字

使用@Bean({"dataSource", "subsystemA-dataSource", "subsystemB-dataSource"})这样的形式指定大量别名

使用@Description("Provides a basic example of a bean")注解进行bean的描述注解

容器的启动

首先抛开SpringBoot的启动方式不谈,我们先来说一下怎么直接启动一个注解相关的Spring容器。

根据官方文档指出,当我们需要使用注解来开发时,应该使用AnnotationConfigApplicationContext来实例化一个Spring的容器:

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