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);
}
输出

3286

被折叠的 条评论
为什么被折叠?



