文章目录
需要的最少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");
}
}