04 Bean注解

1 @Bean注解

用于讲组件注入ioc容器

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

	@AliasFor("name")
	String[] value() default {};

	@AliasFor("value")
	String[] name() default {};
	
	@Deprecated
	Autowire autowire() default Autowire.NO;
	
	/**
	是否支持按照类型注入
	**/
	boolean autowireCandidate() default true;
	
	String initMethod() default "";

	String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;

}
  • 可以用在方法上:将方法的返回值注入到Spring容器
  • 也可以用在注解上

2 使用演示

新建一个模块来演示: 04-spring-annotion-bean

 <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>study.wyy</groupId>
            <artifactId>00-spring-annnotion-common</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

2.1 基本使用

将之前定义person类,注入到spring容器

package study.wyy.spring.anno.bean.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.common.model.Person;

/**
 * @author by wyaoyao
 * @Description
 * @Date 2020/11/16 7:40 下午
 */
@Configuration
public class SpringConfig {

    @Bean
    public Person person(){
       return new Person("T-Mac",20);
    }
}

测试

package study.wyy.spring.anno.bean.config.test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import study.wyy.spring.anno.bean.config.SpringConfig;
import study.wyy.spring.anno.common.model.Person;

/**
 * @author by wyaoyao
 * @Description
 * @Date 2020/11/16 7:42 下午
 */
public class Test {
    @org.junit.Test
    public void test01(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        // bean的名字默认就是方法名
        Person person = context.getBean("person", Person.class);
        System.out.println(person);
    }
}

输出

Person(name=T-Mac, age=20)

总结

  • 用在方法上:将方法的返回值注入到Spring容器
  • bean的名字默认是方法名

1.2 Bean的name

默认是方法的名字,这个已经演示了

可以通过value属性或者name属性指定bean的名称

package study.wyy.spring.anno.bean.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.common.model.Person;

/**
 * @author by wyaoyao
 * @Description
 * @Date 2020/11/16 7:40 下午
 */
@Configuration
public class SpringConfig2 {
    
    @Bean(value = "T-MAC")
    public Person person(){
        return new Person("T-Mac",20);
    }
    
}
   @org.junit.Test
    public void test02(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig2.class);
        // bean的名字默认就是方法名
        Person person = context.getBean("T-MAC", Person.class);
        System.out.println(person);
    }

1.3 autowireCandidate 属性

是否支持按照类型注入, 默认时true

为了演示,取common模块再定义一个部门类,

package study.wyy.spring.anno.common.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author by wyaoyao
 * @Description
 * @Date 2020/11/16 8:22 下午
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {
    // 管理者
    private Person manager;
}

注入一个person bean,和一个部门的bean,其中部门的管理者就是注入的person

package study.wyy.spring.anno.bean.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.common.model.Department;
import study.wyy.spring.anno.common.model.Person;

/**
 * @author by wyaoyao
 * @Description
 * @Date 2020/11/16 7:40 下午
 */
@Configuration
public class SpringConfig3 {
    @Bean(autowireCandidate = true)
    public Person tMac(){
        return new Person("T-Mac",20);
    }
    @Bean(autowireCandidate = true)
    public Department department(@Autowired Person person){
        return new Department(person);
    }
}

测试


    @org.junit.Test
    public void test03(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig3.class);
        // bean的名字默认就是方法名
        Department department = context.getBean("department", Department.class);
        System.out.println(department.getManager());
    }

输出

Person(name=T-Mac, age=20)

改为false

package study.wyy.spring.anno.bean.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.common.model.Department;
import study.wyy.spring.anno.common.model.Person;

/**
 * @author by wyaoyao
 * @Description
 * @Date 2020/11/16 7:40 下午
 */
@Configuration
public class SpringConfig4 {

    @Bean(autowireCandidate = false)
    public Person tMac(){
        return new Person("T-Mac",20);
    }
    @Bean
    public Department department(@Autowired Person person){
        return new Department(person);
    }
}

测试

@org.junit.Test
    public void test04(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig4.class);
        // bean的名字默认就是方法名
        Department department = context.getBean("department", Department.class);
        System.out.println(department.getManager());
    }

结果

.NoSuchBeanDefinitionException: No qualifying bean of type 'study.wyy.spring.anno.common.model.Person' 

这个属性控制的是是否可以被其他组件按类型注入
但是影响的只是@Autowired注解

这里使用的是@Resource, 就不影响

package study.wyy.spring.anno.bean.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.common.model.Department;
import study.wyy.spring.anno.common.model.Person;

import javax.annotation.Resource;

/**
 * @author by wyaoyao
 * @Description
 * @Date 2020/11/16 7:40 下午
 */
@Configuration
public class SpringConfig5 {

    @Resource
    Person person;

    @Bean(autowireCandidate = false)
    public Person person(){
        return new Person("T-Mac",20);
    }
    @Bean
    public Department department(){
        return new Department(person);
    }
}

测试

 @org.junit.Test
    public void test05(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig5.class);
        // bean的名字默认就是方法名
        Department department = context.getBean("department", Department.class);
        System.out.println(department.getManager());
    }
Person(name=T-Mac, age=20)

1.3 bean的初始化和销毁

  • initMethod属性:指定bean的初始化方法,一般不推荐使用,可以自己编码去做
  • destroyMethod属性:The optional name of a method to call on the bean instance upon closing the application context(再关闭spring 容器的时候会调用, 该属性指定的方法必须没有返回值)

修改一下Department,

  • 指定一个init方法:打印manager属性
  • 指定一个destroy方法:设置manager为null
package study.wyy.spring.anno.common.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author by wyaoyao
 * @Description
 * @Date 2020/11/16 8:22 下午
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {
    // 管理者
    private Person manager;

    public void init(){
        System.out.println(manager);
    }

    public void destroy(){
        setManager(null);
        System.out.println("destroy.....");
    }
}

package study.wyy.spring.anno.bean.config;

import jdk.nashorn.internal.ir.CallNode;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.common.model.Department;
import study.wyy.spring.anno.common.model.Person;

import javax.annotation.Resource;

/**
 * @author by wyaoyao
 * @Description
 * @Date 2020/11/16 7:40 下午
 */
@Configuration
public class SpringConfig6 {
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public Department department() {
        Person person = new Person("T-Mac", 20);
        Department department = new Department(person);
        return department;
    }

}

测试

@org.junit.Test
    public void test06(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig6.class);
        // bean的名字默认就是方法名
        Department department = context.getBean("department", Department.class);

    }

输出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值