spring bean定义相关

需要的最少jar包

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>${spring.version}</version>
</dependency>

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aop</artifactId>
	<version>${spring.version}</version>
</dependency>

helloworld程序

注解式配置:

@Configuration//说明此类是一个配置类
@ComponentScan("springBase.show")//定义扫描包的路径,自动扫描bean,扫描带有@Component等注解的类
public class JavaConfig {
	@Bean//定义一个bean
	public Student student() {
		return new Student();
	}
	public static void main(String[] args) {
		//注解方式初始化上下文
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
		//获取bean
		Student student = context.getBean(Student.class);
		System.out.println(student);
		//关闭上下文,回收资源
		context.close();
	}
}
public class Student {

}

定义一个bean(默认单例)

@Bean方式 默认的bean名称为方法名称

	@Bean
	public Student student() {
		return new Student();
	}

@Component方式 默认bean名称为类名称首字母小写

@Component
public class Student {

}

bean的作用域

单立、原型、会话、请求
单立

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)//或者不指定scop也行,默认单立
public class DemoPrototypeService {
}

原型

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DemoPrototypeService {
}

会话
会话作用域用于webApp中
proxyMode由使用接口还是类来决定
如果是直接使用类进行定义

//定义方
@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION,proxyMode=ScopedProxyMode.INTERFACES)
public class ShoppingCart{
}
//使用方:
@Autowired
private ShoppingCart shoppingCart;

如果使用接口

//定义方
public interface ShoppingCart {
}
@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION,proxyMode=ScopedProxyMode.INTERFACES)
public class ShoppingCartImpl implements ShoppingCart{
}
//使用方:
@Autowired
private ShoppingCart shoppingCart;

请求
参考会话只是value不一样,proxyMode一样

@Scope(value=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.INTERFACES)

自动装配

@Autowired//set方法也可
private Student student;

导入其他配置(java代码式)@Import

@Import(StudentConfig.class)//这里并没有扫描到Student

导入其他配置(xml代码式)@Import

@ImportResource("classpath:student.xml")

选择性的加载bean(profile)

@Configuration
public class JavaConfig {
	@Bean
	@Profile("dev")//声明一个profile bean
	public DemoBean devDemoBean() {// 开发配置需要生成的bean
		return new DemoBean("form development profile");
	}

	@Bean
	@Profile("prod")
	public DemoBean prodDemoBean() {// 产品配置需要生成的bean
		return new DemoBean("form production profile");
	}
}

激活profile

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("dev");// 进行配置环境设置

或者

@ActiveProfiles("dev")

条件化bean

条件类:

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class Conditional1 implements Condition {
	//此处的ConditionContext和AnnotatedTypeMetadata很重要,可以做甚多事情
	@Override
	public boolean matches(ConditionContext paramConditionContext, AnnotatedTypeMetadata paramAnnotatedTypeMetadata) {
		return true;//此条件类生效
	}
}
public class Conditional2 implements Condition {
	@Override
	public boolean matches(ConditionContext paramConditionContext, AnnotatedTypeMetadata paramAnnotatedTypeMetadata) {
		return false;
	}
}

bean类:

import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Service;
@Service
@Conditional(value = { Conditional1.class })//此bean生效
public class Service1 implements IService {
	@Override
	public String show() {
		return "I am service1";
	}
}
@Service
@Conditional(value = { Conditional2.class })
public class Service2 implements IService {
	@Override
	public String show() {
		return "I am service2";
	}
}

bean的歧义性问题

如果有多个bean实现同一个接口,在自动装配的时候就会产生歧义

No qualifying bean of type 'springBase.show.IStudentService' available: expected single matching bean but found 2: student1,student2

方式一:首选bean@Primary

@Component
@Primary
public class Student1 implements IStudentService{
}

方式二:使用限定符@Qualifier

//声明
@Component
@Qualifier("sss")
public class Student1 implements IStudentService{	
}
//使用
@Autowired
@Qualifier("sss")
private IStudentService student;

方式二:使用限定符注解
限定符注解还可以解决无法多次使用@Qualifier注解的问题,因为如果需要使用多次限定符,java是不允许同一注解出现多次的,可以先声明一个如下的注解,然后可以将此注解和限定符一起使用

@Target({ java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD,
	java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE,
	java.lang.annotation.ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Qualifier("SZ")
public @interface SZ {
}

@Configuration
@ComponentScan(basePackages="springBase.show")
public class JavaConfig {
	@Autowired
	@SZ
	private IStudentService student;
	
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
		JavaConfig javaConfig = context.getBean(JavaConfig.class);
		System.out.println(javaConfig.student);
		context.close();
	}
}

bean的加载顺序

使用@DependsOn,以下A一定先于B加载

@Component
public class A {
	public A(){
		System.out.println("A init");
	}
}
@Component
@DependsOn(value="a")
public class B {
	public B(){
		System.out.println("B init");
	}
}
发布了36 篇原创文章 · 获赞 5 · 访问量 5358

猜你喜欢

转载自blog.csdn.net/weixin_43060721/article/details/82632428