@Lazy
懒加载模式
默认是单实例的,ioc容器启动就会调用方法,并放在容器中,以后就从容器中拿,但是如果加了@Lazy注解时,容器启动时不会去创建Bean,在第一次使用时才会创建Bean并初始化
Demo:
/**
* 懒加载:
* 单实例情况下,容器启动不会去创建bean对象,在第一次使用的时候才会创建bean对象,并初始化
*
* */
@Lazy
//默认是单实例的,ioc容器启动就会调用方法,并放在容器中,以后就从容器中拿
//如果改成多实例的话,ioc容器启动时不会调用方法
@Scope("prototype") //singleton 是单实例的
//给容器注册一个bean,类型是返回值,id默认是用方法名作为id
//当指定value时,value的值作为该bean的id,不会再去看方法名是什么了
@Bean(value = "person")
public Person person01(){
return new Person("snail",20);
}
@Conditional
按照一定的条件进行判断,满足条件给容器中注册bean
1、需要实现org.springframework.context.annotation下的Condition接口,重写Condition下的方法
Condition接口:
public interface Condition {
/**
* Determine if the condition matches.
* @param context the condition context
* @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
* or {@link org.springframework.core.type.MethodMetadata method} being checked.
* @return {@code true} if the condition matches and the component can be registered
* or {@code false} to veto registration.
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
比如实现该接口的一个小Demo:
public class WindowsCondition implements Condition {
/**
* ConditionContext:判断条件能使用的上下文
* AnnotatedTypeMetadata:注释信息
* */
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//获取IOC中的beanfactory
ConfigurableListableBeanFactory beanFactory=context.getBeanFactory();
//获取类加载器
ClassLoader classLoader=context.getClassLoader();
//获取当前环境信息
Environment environment=context.getEnvironment();
//获取bean的定义的注册类
BeanDefinitionRegistry registry=context.getRegistry();
String env=environment.getProperty("os.name");
if (env.contains("Windows")){
return true;
}
else
return false;
}
}
2、在Bean注册时加上注解@Conditional({实现接口的类名1.class,实现接口的类名2.class})
如下:
@Conditional({WindowsCondition.class})
@Bean(value="niuniu")
public Person person02(){
return new Person("牛牛",18);
}
@Import
标注在类上,并非方法上
可以直接快速注册到容器中
@Import({color.class, MyImportSelector.class})
public class MainConfig2 {}
其中:color.class就是一个要注册进来的Bean
@Import的ImportSelector方式
1、实现ImportSelector接口,最终返回要注册是Bean
public class MyImportSelector implements ImportSelector {
/**
*
* @param importingClassMetadata
* @return 导入到组件中的类名
* AnnotationMetadata 标注了@Import的类上的所有注解
*
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.dwd.snail.testspring.test.bean.blue","com.dwd.snail.testspring.test.bean.yellow"};
}
}
2、在配置类中引用实现该接口的方法
@Import({color.class, MyImportSelector.class})
public class MainConfig2 {}
其中 MyImportSelector就是实现接口的方法
使用Spring的FactoryBean注册
1、创建一个工厂Bean,实现FactoryBean接口
//创建一个工厂bean
public class ColorFactoryBean implements FactoryBean<color> {
//返回一个color对象,会添加到容器中
@Override
public color getObject() throws Exception {
return new color();
}
@Override
public Class<?> getObjectType() {
return color.class;
}
//是否单实例?单实例只会在容器中保存一份
@Override
public boolean isSingleton() {
return true;
}
}
2、注册这个工厂Bean
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
总结下给容器注册Bean的方法:
/**
- 给容器中注册组件
- 1、包扫描+组件标注注解(@Controler@Service@Repository@Component),仅限于本工程内,带这些注解的bean自动注入
- 2、@Bean 用于未带注解的或者第三方jar包中的bean注册
- 3、@Import方式来导组件,在配置类中注解
- 4、@Import-ImportSelector来导入
- 5、使用Spring的FactoryBean(工厂bean)
- */
网友评论