SpringBoot基础系列文章
配置文件spring-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--xml方式声明自己开发的bean-->
<bean id="person" class="com.xc.entity.Person"/>
<bean class="com.xc.entity.Person"/>
<bean class="com.xc.entity.Person"/>
<!--xml方式声明第三方开发的bean-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>
</beans>
加载xml
public class App {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-bean.xml");
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
}
}
输出结果:
person
com.xc.entity.Person#0
com.xc.entity.Person#1
dataSource
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
System.err.println(beanDefinitionName);
}
}
}
public class MyConfig {
}
使用**AnnotationConfigApplicationContext
**对象加载MyConfig,即使MyConfig类什么注解没有,也会被注册为bean。
@Component
**或其他衍生注解**@Service
**、**@Controller
**、**@Repository
**@Service
public class BookServiceImpl implements BookService {
}
由于我们无法在第三方提供的技术源代码中去添加上述4个注解,因此当你需要**加载第三方开发的bean
**的时候可以使用**@Component
**和**@Configuration
**都可以,一般引入第三方倾向于后者。
//@Component
@Configuration
public class DbConfig {
@Bean
public DruidDataSource dataSource(){
return new DruidDataSource();
}
@Bean
public Cat cat(){
Cat cat = new Cat();
cat.setDruidDataSource(dataSource());
return cat;
}
}
@Configuration(proxyBeanMethods = true)
**:默认设置,使用了**cglib动态代理
**,cat里的dataSource和@Bean创建的dataSource是**同一个对象
**,可以理解为**单例
@Configuration(proxyBeanMethods = false)
**:此时和@Component注解功能一样,cat里的dataSource和@Bean创建的dataSource**不是同一个对象
**,可以理解为**多例
不存在依赖调用
**的话,可以设置为false,可以避免拦截方法进行代理操作,**提升性能
**FactoryBean
**,也可以用于**声明bean
**泛型
**指定类型的对象public class DogFactoryBean implements FactoryBean<Dog> {
//创建bean的复杂过程
@Override
public Dog getObject() throws Exception {
Dog d = new Dog();
//.........
return d;
}
//bean的类型
@Override
public Class<?> getObjectType() {
return Dog.class;
}
//bean是否单例
@Override
public boolean isSingleton() {
return true;
}
}
配置类
public class MyConfig {
@Bean
public DogFactoryBean dog(){
return new DogFactoryBean();
}
}
启动类
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println(context.getBean("dog"));
}
}
@ImportResource
**在配置类上直接写上要被融合的xml配置文件名即可**@Configuration
@ImportResource(locations = "spring-bean.xml")
public class SpringConfig {
}
方式一:无参构造
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
//上下文容器对象已经初始化完毕后,手工加载bean
ctx.register(Mouse.class);
}
}
方式二:多参构造
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
//上下文容器对象已经初始化完毕后,手工加载bean
ctx.registerBean("tom", Cat.class,"花猫",3);
}
}
@Configuration
//@Import(Pig.class)
@Import({Dog.class,Cat.class})
public class MyConfig {
}
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
System.err.println(beanDefinitionName);
}
}
}
输出结果:
myConfig
com.xc.springboot.bean.Dog
com.xc.springboot.bean.Cat
判断语句
**就可以实现对**bean的加载控制
**全路径类名字符串
**public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata metadata) {
System.out.println("元数据Class名称:" + metadata.getClassName());
//各种条件的判定,判定完毕后,决定是否装载指定的bean
boolean flag = metadata.hasAnnotation("org.springframework.context.annotation.Configuration");
if(flag){
return new String[]{"com.xc.springboot.bean.Dog"};
}
return new String[]{"com.xc.springboot.bean.Cat"};
}
}
配置类
@Configuration
@Import(MyImportSelector.class)
public class MyConfig {
}
启动类
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
System.err.println(beanDefinitionName);
}
}
}
输出结果:
元数据Class名称:com.xc.springboot.bean.MyConfig
myConfig
com.xc.springboot.bean.Dog
Bean定义(beanDefinition)
**注册创建新的beanpublic class MyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition =
BeanDefinitionBuilder.rootBeanDefinition(BookService.class).getBeanDefinition();
registry.registerBeanDefinition("bookService",beanDefinition);
}
}
postProcessBeanDefinitionRegistry
**:用于注册新的BeanDefinition**postProcessBeanFactory
**:用于在BeanFactory**准备好后
**进行自定义操作**最后
**的处理器(在以上处理后执行此操作),如果想bean最后确定一个值,可以在这里操作public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 通过 BeanDefinitionBuilder 创建一个新的 Bean 定义
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MyCustomBean.class);
// 注册这个 bean 定义到 registry 中
registry.registerBeanDefinition("myCustomBean", builder.getBeanDefinition());
System.out.println("Bean definition registered: myCustomBean");
}
@Override
public void postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 在这里可以对 BeanFactory 进行进一步的配置
System.out.println("Bean factory post-processing");
}
}
注意:所有通过@Import导入的bean名称为全路径名