Spring @Bean 注解使用示例

x33g5p2x  于2022-09-24 转载在 Spring  
字(7.5k)|赞(0)|评价(0)|浏览(361)

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

我们可以在 @Configuration 类中创建 bean,并在方法中注释 @Bean。在 @Configuration 类中,创建带有 @Bean 注释的方法,并且方法需要返回一个 bean 的对象。在我们的示例中,我们将两个类 BeanABeanB 创建为 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 名称

我们可以使用 @Bean 注释的 name 属性更改默认 bean 名称。默认的 bean 名称是 @Bean 注释的方法名称。当我们使用 name 属性分配 bean 名称时,默认 bean 名称将不可用。可以将多个 bean 名称分配为单个 bean 的数组。要指定 bean 名称,我们可以使用 namevalue 属性。找到例子。
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 名称是 b1Beanb2Bean。我们可以通过它们的名称访问 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();
	}
}

b1Beanb2Bean 将返回相同的 bean。
输出

Bean A
Bean B
Bean B

initMethod 和 destroyMethod

initMethoddestroyMethod@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 方法。保证内部 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

将@Scope、@Lazy、@DependsOn 和@Primary 与@Bean 一起使用

@Bean 可与 @Scope@Lazy@DependsOn@Primary 等一起使用。
1。使用 @Scope
bean 的默认范围是 singleton。我们可以使用 @Scope 注解更改 bean 范围。 Bean 范围是 prototyperequestsession 等。找到一个示例示例将 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();
	}
        ------	
}

@Component 类中的 @Bean

@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

相关文章