文章目录
- 1.XML方式声明bean
- 2.XML+注解方式声明bean
- 3.纯注解加载Bean
- 关于FactoryBean接口的类
- 关于@Configuration注解中的proxyBeanMethods属性
- 4.使用@Import注解导入
- 5.使用上下文对象在容器初始化完毕后注入bean
- 6.通过ImportSelector接口加载bean
- 7.通过ImportBeanDefinitionRegistrar接口创建bean
- 8.BeanDefinitionRegistryPostProcessor决定bean的创建
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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>
<!--声明自定义bean-->
<bean id="testService" class="com.Learning1.service.impl.Service" scope="singleton"/>
<!--声明第三方开发bean-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>
</beans>
2.XML+注解方式声明bean
- 此种方式需要在xml配置文件中声明命名空间
开启命名空间后,指定包扫描位置
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.Learning2"/>
</beans>
然后使用@Component注解以及其衍生注解@Controller,@Service,@Repository定义bean
@Service
public class AccountServiceImpl implements AccountService {
}
如果要定义第三方bean,需要使用@Bean注解定义在方法上面,并将所在类定义为配置类或Bean
@Configuration
//@Component
public class DbConfig {
@Bean
public DruidDataSource getDataSource(){
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
}
@Configuration注解包含了@Component注解
3.纯注解加载Bean
将xml配置文件改为一个配置类,用配置类取代xml配置的功能
@Configuration
@ComponentScan("com.Learning2")
public class SpringConfig {
}
关于FactoryBean接口的类
实现FactoryBean接口的类也是用来创建bean的,它存在的意义就在于能够在bean创建之前进行一系列的前置工作,比如判断创建条件,设置bean的信息等
对实现了FactoryBean接口的类加上@Bean注解,创建出来的bean不是那个类而是工厂造出来的对象的bean
public class TestDaoFactoryBean implements FactoryBean<TestDao> {
@Override
public TestDao getObject() throws Exception {
return new TestDaoImpl();
}
@Override
public Class<?> getObjectType() {
return TestDao.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
关于@Configuration注解中的proxyBeanMethods属性
proxyBeanMethods=true可以保证调用有@Configuration注解的类的方法得到的对象是从spring容器中获取的而不是重新创建的。proxyBeanMethods的默认值是true
4.使用@Import注解导入
将需要其对象注册为Bean的类作为参数填入@Import注解中即可
这种形式可以有效的降低源代码与spring技术的耦合度
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}
5.使用上下文对象在容器初始化完毕后注入bean
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
applicationContext.register(UserService.class);
applicationContext.registerBean("testDao",TestDao.class);
}
}
6.通过ImportSelector接口加载bean
在配置类中导入实现了ImportSelector接口的类,实现对导入源的编程式处理
谁引用了这个类,这个类就可以获取这个类的一系列信息
@Import({MyImportSelector.class})
@EnableTransactionManagement
public class SpringConfig {
}
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
importingClassMetadata.hasAnnotation("org.springframework.context.annotation.Configuration");
return new String[]{"com.Learning2.Dog"};
}
}
7.通过ImportBeanDefinitionRegistrar接口创建bean
这种方法深入到bean的定义过程,使用方法和上一种类似
导入实现了ImportBeanDefinitionRegistrar接口的类,通过beanDefinition的注册器注册实名bean,实现对容器中bean的裁定
@Import({MyImportBeanDefinitionRegistrar.class})
public class SpringConfig {
}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = BeanDefinitionBuilder
.rootBeanDefinition(Dog.class)
.getBeanDefinition();
registry.registerBeanDefinition("dodo",beanDefinition);
}
}
8.BeanDefinitionRegistryPostProcessor决定bean的创建
这个接口是bean创建的最终决定接口,实现了这个接口的类可以处理之前过程中已经创建的bean,也可以新增bean,是一个最终裁定的接口
使用方式和上一个接口的方式类似
导入实现了BeanDefinitionRegistryPostProcessor接口的类,通过BeanDefinition的注册器注册实名bean,实现对容器中bean的最终裁定
@Import({MyPostProcessor.class})
public class SpringConfig {
}
public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry)
throws BeansException {
BeanDefinition beanDefinition = BeanDefinitionBuilder
.rootBeanDefinition(Dog.class)
.getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("dodo",beanDefinition);
}
@Override
public void postProcessBeanFactory(
ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
除了上面8种方式spring还有一些其他的加载bean的方式,这里就不再叙述了。