Spring源码学习——通过配置类向容器中注入Bean

以代码的方式向容器中注入Bean,示例如下:

实体类

package Dao;

public class Person {
    
    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public Person() {
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
//省略get,set方法
}

配置类

package config;

import Dao.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {

    @Bean
    public Person person(){
        return new Person("ls", 12);
    }
}

其中有两个注解这里说明下: 

@Configuration

这个注解的作用是告诉Spring容器这是个配置类 。会在容器创建的时候扫描该类,并把该类下的Bean注入到容器中。

@Bean

告诉容器该方法是要注入容器中的Bean。

注意:

1、注入的Bean的类型为返回值类型;

2、Bean的id默认为方法名

这个注解中有几个参数,我们来看下源码:

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.core.annotation.AliasFor;


@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {

    /**
     * 可以通过该属性修改Bean的id
     * @return
     */
    @AliasFor("name")
    String[] value() default {};

    /**
     * 可以通过该属性修改Bean的id
     * @return
     */
    @AliasFor("value")
    String[] name() default {};


    @Deprecated
    Autowire autowire() default Autowire.NO;

   
    boolean autowireCandidate() default true;

    /**
     * 指定该Bean的初始化方法
     * @return
     */
    String initMethod() default "";

    /**
     * 指定该Bean的销毁方法
     * @return
     */
    String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;

}

需要注意的是,不可以同时设置value和name,因为源码上已经标出了这两个属性互为别名(@AliasFor),如果同时设置将会报出如下错误:

Exception in thread "main" org.springframework.core.annotation.AnnotationConfigurationException: In AnnotationAttributes for annotation [org.springframework.context.annotation.Bean] declared on public Dao.Person config.MyConfig.person(), attribute 'name' and its alias 'value' are declared with values of [{x}] and [{y}], but only one is permitted.
	at org.springframework.core.annotation.AnnotationUtils.lambda$postProcessAnnotationAttributes$0(AnnotationUtils.java:1355)
	at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
	at org.springframework.core.annotation.AnnotationUtils.postProcessAnnotationAttributes(AnnotationUtils.java:1336)
	at org.springframework.core.annotation.AnnotatedElementUtils.getMergedAnnotationAttributes(AnnotatedElementUtils.java:365)
	at org.springframework.core.type.StandardMethodMetadata.getAnnotationAttributes(StandardMethodMetadata.java:127)
	at org.springframework.context.annotation.AnnotationConfigUtils.attributesFor(AnnotationConfigUtils.java:285)
	at org.springframework.context.annotation.AnnotationConfigUtils.attributesFor(AnnotationConfigUtils.java:280)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:189)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:327)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:232)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:691)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:528)
	at org.springframework.context.annotation.AnnotationConfigApplicationContext.(AnnotationConfigApplicationContext.java:88)
	at test.main(test.java:10)

测试类

import config.MyConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class test {

    public static void main(String[] args) {
        //创建容器
        AnnotationConfigApplicationContext annotationConfigApplicationContext 
                        = new AnnotationConfigApplicationContext(MyConfig.class);
        //通过id获得容器中的Bean
        Object person = annotationConfigApplicationContext.getBean("person");
        //查看Bean的类型
        System.out.println("id为person的Bean类型为------>" + person.getClass());
        //打印
        System.out.println(person);
    }
}

输出

id为person的Bean类型为------>class Dao.Person
Person{name='ls', age=12}

 

你可能感兴趣的:(Spring源码学习)