一、加载方式一
- XML方式声明bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--声明自定义bean-->
<bean id="studyService" class="com.study.service.impl.StudyServiceImpl" scope="singleton"/>
<!--声明第三方开发bean-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>
</beans>
二、加载方式二
1.XML+注解方式声明bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 组件扫描,指定加载bean的位置 -->
<context:component-scan base-package="com.study"/>
</beans>
2.使用@Component与衍生注解@Controller 、@Service、@Repository进行bean定义
@Service
public class StudyServiceImpl implements StudyService {
}
3.使用@Bean定义第三方bean,并将所在类定义为配置类或Bean
@Component
public class DbConfig {
@Bean
public DruidDataSource getDataSource(){
DruidDataSource ds = new DruidDataSource();
return ds;
}
}
三、加载方式三
注解方式声明配置类:通过对包的扫描加载bean
@Configuration
@ComponentScan("com.study")
public class SpringConfig {
@Bean
public DruidDataSource getDataSource(){
DruidDataSource ds = new DruidDataSource();
return ds;
}
}
扩展1
初始化实现FactoryBean接口的类,实现对bean加载到容器之前的批处理操作
public class StudyFactoryBean implements FactoryBean {
public Study getObject() throws Exception {
Study study = new Study();
// 进行book对象相关的初始化工作
return study;
}
public Class getObjectType() {
return Study.class;
}
}
@Configuration
public class SpringConfig {
@Bean
//显示的表示为配置StudyFactoryBean ,但实际上配置的是Study
public StudyFactoryBean book(){
return new StudyFactoryBean();
}
}
扩展2
加载配置类并加载配置文件
@Configuration
@ComponentScan("com.study")
@ImportResource("applicationContext-config.xml")
public class SpringConfig {
}
扩展3
使用proxyBeanMethods=true调用此方法得到的对象是从容器中获取的而不是重新创建的
@Configuration(proxyBeanMethods = false)
public class SpringConfig {
@Bean
public Study study(){
System.out.println("study init ...");
return new Study();
}
}
public class AppObject {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
SpringConfig config = ctx.getBean("Config", Config.class);
config.study();
}
}
四、加载方式四
使用@Import注解导入要注入的bean对应的字节码
@Import(student.class)
public class SpringConfig { }
被导入的bean无需使用注解声明为bean
public class student { }
此形式可以有效的降低源代码与Spring技术的耦合度,在spring技术底层及诸多框架的整合中被大量使用
扩展4
使用@Import注解导入配置类
@Import(DbConfig.class)
public class SpringConfig { }
五、加载方式五
使用上下文对象在容器初始化完毕后注入bean:AnnotationConfigApplicationContext调用register方法
public class AppImport {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig5.class);
ctx.register(student.class);
String[] names = ctx.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
}
需要在容器初始化之后才能使用这种方法。若重复加载同一个bean,后加载的将会覆盖前加载的。
六、加载方式六
导入实现了ImportSelector接口的类,实现对导入源的编程式处理
public class MyImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata metadata) {
// 使用metadata可以获取到导入该类的大量属性,通过对这些属性进行判断,可以达到动态注入bean的效果
boolean flag = metadata.hasAnnotation("org.springframework.context.annotation.Import"); if(flag){
return new String[]{"com.domain.study"};
}
return new String[]{"com.domain.student"};
}
}
七、加载方式七
导入实现了ImportBeanDefinitionRegistrar接口的类,通过BeanDefinition的注册器注册实名bean,实现对 容器中bean的裁定,例如对现有bean的覆盖,进而达成不修改源代码的情况下更换实现的效果
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = BeanDefinitionBuilder .rootBeanDefinition(StudyServiceImpl2.class) .getBeanDefinition(); registry.registerBeanDefinition("studyService", beanDefinition);
}
}
八、加载方式八
导入实现了BeanDefinitionRegistryPostProcessor接口的类,通过BeanDefinition的注册器注册实名bean, 实现对容器中bean的最终裁定
public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = BeanDefinitionBuilder .rootBeanDefinition(BookServiceImpl4.class) .getBeanDefinition(); registry.registerBeanDefinition("bookService", beanDefinition);
}
}