Spring @Bean
注释表明一个方法生成了一个由 Spring 容器管理的 bean。可以在 @Configuration
和 @Component
类中创建 Spring @Bean
方法。 bean 的默认范围是单例。 @Bean
注解可以与 @Scope
、@Lazy
、@DependsOn
、@Primary
等注解结合使用。
找到 @Bean
注解的可选方法。
autowireCandidate:布尔值,用于确定此 bean 是否是自动装配到其他 bean 的候选对象。默认为真。它在 Spring 5.1 中引入。
initMethod:在初始化期间调用 bean 实例的方法名称。默认是没有要调用的 init 方法。
destroyMethod:关闭应用程序上下文时调用 bean 实例的方法名称。该方法必须没有参数,但可以抛出异常。
名称:此 bean 的名称。默认 bean 名称是方法名称。
值:名称的别名。
在此页面上,我们将通过示例详细讨论 @Bean
方法。
我们可以在 @Configuration
类中创建 bean,并在方法中注释 @Bean
。在 @Configuration
类中,创建带有 @Bean
注释的方法,并且方法需要返回一个 bean 的对象。在我们的示例中,我们将两个类 BeanA
和 BeanB
创建为 Spring bean。找到使用 @Bean
注解创建这些类的 bean 的代码。
AppConfig.java
package com.concretepage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public BeanA getBeanA() {
BeanA beanA = new BeanA();
beanA.setName("Bean A");
return beanA;
}
@Bean
public BeanB getBeanB() {
return new BeanB("Bean B");
}
}
默认的 bean 名称将是方法名称。这意味着第一个 bean 名称是 getBeanA
,第二个 bean 名称是 getBeanB
。
BeanA.java
package com.concretepage;
public class BeanA {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
BeanB.java
package com.concretepage;
public class BeanB {
private String name;
public BeanB(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
可以通过 bean 类或 bean 名称访问 bean,也可以使用 @Autowired
注释将其注入组件中。
MySpringApp.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
//BeanA beanA = ctx.getBean(BeanA.class);
BeanA beanA = (BeanA) ctx.getBean("getBeanA");
System.out.println(beanA.getName());
BeanB beanB = ctx.getBean(BeanB.class);
//BeanB beanB = (BeanB) ctx.getBean("getBeanB");
System.out.println(beanB.getName());
ctx.registerShutdownHook();
ctx.close();
}
}
输出
Bean A
Bean B
我们可以使用 @Bean
注释的 name
属性更改默认 bean 名称。默认的 bean 名称是 @Bean
注释的方法名称。当我们使用 name
属性分配 bean 名称时,默认 bean 名称将不可用。可以将多个 bean 名称分配为单个 bean 的数组。要指定 bean 名称,我们可以使用 name
或 value
属性。找到例子。
AppConfig.java
@Configuration
public class AppConfig {
@Bean("a1Bean")
public BeanA getBeanA() {
BeanA beanA = new BeanA();
beanA.setName("Bean A");
return beanA;
}
@Bean(name={"b1Bean", "b2Bean"})
public BeanB getBeanB() {
return new BeanB("Bean B");
}
}
第一个 bean 名称是 a1Bean
,第二个 bean 名称是 b1Bean
和 b2Bean
。我们可以通过它们的名称访问 bean,如下所示。
MySpringApp.java
public class MySpringApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
BeanA beanA = (BeanA) ctx.getBean("a1Bean");
System.out.println(beanA.getName());
BeanB beanB1 = (BeanB) ctx.getBean("b1Bean");
System.out.println(beanB1.getName());
BeanB beanB2 = (BeanB) ctx.getBean("b2Bean");
System.out.println(beanB2.getName());
ctx.registerShutdownHook();
ctx.close();
}
}
b1Bean
和 b2Bean
将返回相同的 bean。
输出
Bean A
Bean B
Bean B
initMethod
和 destroyMethod
是 @Bean
注释的属性。在 bean 中,我们可以有初始化和销毁方法。 initMethod
指定任何初始化方法,destroyMethod
方法指定任何销毁方法。初始化方法将在创建 bean 之后调用,而销毁方法将在关闭应用程序上下文之前调用。
Work.java
package com.concretepage;
public class Work {
public void initWork() {
System.out.println("--- Initializing Work ---");
}
public void doWork() {
System.out.println("-- Doing my Work ---");
}
public void closeWork() {
System.out.println("-- Closing Work ---");
}
}
AppConfig.java
package com.concretepage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean(name="mywork", initMethod="initWork", destroyMethod="closeWork")
public Work getWork() {
return new Work();
}
}
MySpringApp.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
Work work = (Work) ctx.getBean("mywork");
work.doWork();
ctx.registerShutdownHook();
ctx.close();
}
}
输出
--- Initializing Work ---
-- Doing my Work ---
-- Closing Work ---
在同一个配置类中,我们可以通过直接调用其他 @Bean
方法来引用一个 @Bean
方法。保证内部 bean 引用尊重范围和 AOP 语义。找到例子。
AppConfig.java
package com.concretepage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public Person getPerson() {
return new Person("Mahesh");
}
@Bean
public School getSchool() {
return new School(getPerson());
}
}
Person.java
package com.concretepage;
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
School.java
package com.concretepage;
public class School {
private String schoolName = "ABC School";
private String principal;
public School(Person person) {
this.principal = person.getName();
}
public String getSchoolName() {
return schoolName;
}
public String getPrincipal() {
return principal;
}
}
MySpringApp.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
School school = ctx.getBean(School.class);
System.out.println(school.getPrincipal());
System.out.println(school.getSchoolName());
ctx.registerShutdownHook();
ctx.close();
}
}
输出
Mahesh
ABC School
@Bean
可与 @Scope
、@Lazy
、@DependsOn
、@Primary
等一起使用。
1。使用 @Scope
bean 的默认范围是 singleton
。我们可以使用 @Scope
注解更改 bean 范围。 Bean 范围是 prototype
、request
、session
等。找到一个示例示例将 bean 范围更改为 prototype
。
AppConfig.java
@Configuration
public class AppConfig {
@Bean
@Scope("prototype")
public BeanA getBeanA() {
return new BeanA();
}
}
2。使用 @Lazy
@Lazy
指示 bean 是否要延迟初始化。
AppConfig.java
@Configuration
public class AppConfig {
@Bean
@Scope("prototype")
@Lazy(true)
public BeanA getBeanA() {
return new BeanA();
}
}
3。使用 @DependsOn
@DependsOn
指定当前 bean 所依赖的 bean。
AppConfig.java
@Configuration
public class AppConfig {
@Bean
@Scope("prototype")
@DependsOn("myBeanB")
public BeanA getBeanA() {
return new BeanA();
}
@Bean("myBeanB")
public BeanB getBeanB() {
return new BeanB();
}
}
4。使用 @Primary
@Primary
表示当多个候选者有资格自动装配单值依赖项时,应优先考虑 bean。
AppConfig.java
@Configuration
public class AppConfig {
@Bean
@Primary
public BeanA getBeanA() {
return new BeanA();
}
------
}
@Bean
方法也可以在使用 @Component
注释的类中声明。在这种情况下,@Bean
方法在 lite 模式下处理。这里的 @Bean
方法将被容器视为普通的工厂方法,并正确地遵循范围和生命周期回调。@Configuration
和 @Component
类的 @Bean
方法的区别在于 @Component
类的 bean 不支持内部 bean 引用。在 lite 模式下,如果 @Bean
方法正在调用另一个 bean 方法,它将是标准 Java 方法调用。找到在 @Component
类中创建 @Bean
方法的示例。
app.java
package com.concretepage;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class Utility {
public int addNumbers(int num1, int num2) {
return num1 + num2;
}
@Bean
public Square getSquare() {
return new Square();
}
}
Square.java
package com.concretepage;
public class Square {
public int getSquare(int arm) {
return arm * arm;
}
}
AppConfig.java
package com.concretepage;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.concretepage")
public class AppConfig {
}
MySpringApp.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
Square square = ctx.getBean(Square.class);
int num = 10;
System.out.println("Square of " + num + " = "+square.getSquare(10));
ctx.registerShutdownHook();
ctx.close();
}
}
输出
Square of 10 = 100
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.concretepage.com/spring-5/spring-bean-annotation
内容来源于网络,如有侵权,请联系作者删除!