Bean的加载方式

简介: Bean的加载方式1.XML方式声明bean2.XML+注解方式声明bean3.注解方式声明配置类扩展1——FactoryBean扩展2——配置类中导入原始的配置文件(系统迁移)扩展3——proxyBeanMethods4.使用@Import导入要注入的bean扩展4——使用@Import注解还可以导入配置类5.使用上下文对象在容器初始化完毕后注入bean6.导入实现了ImportSelector接口的类,实现对导入源的编程式处理bean的加载方式(七)bean的加载方式(八)

Bean的加载方式



Bean的加载方式

1.XML方式声明bean

2.XML+注解方式声明bean

3.注解方式声明配置类

扩展1——FactoryBean

扩展2——配置类中导入原始的配置文件(系统迁移)

扩展3——proxyBeanMethods

4.使用@Import导入要注入的bean

扩展4——使用@Import注解还可以导入配置类

5.使用上下文对象在容器初始化完毕后注入bean

6.导入实现了ImportSelector接口的类,实现对导入源的编程式处理

bean的加载方式(七)

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">
  <!--声明自定义bean-->
  <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"/>
  <!--声明第三方开发bean-->
  <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>
</beans>


2.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">
  <context:component-scan base-package="com.spring"/>
</beans>


@Service
public class BookServiceImpl implements BookService {
}


(1)使用@Bean定义第三方bean,并将所在类定义为配置类


@Configuration
public class DbConfig {
  @Bean
  public DruidDataSource getDataSource(){
    DruidDataSource ds = new DruidDataSource();
    return ds;
} }


(2)使用@Component及其衍生注解@Controller 、 @Service、 @Repository定义bean

注意:@Controller 、 @Service、 @Repository作用其实跟Component注解一样,只是给开发人员

看的,让我们能够便于分辨组件的作用。


3.注解方式声明配置类


(1)定义配置类


@ComponentScan({"com.spring.bean"})
public class SpringConfig3 {
  @Bean
  public DruidDataSource getDataSource(){
    DruidDataSource ds = new DruidDataSource();
    return ds;
} }


(2)使用AnnotationConfigApplicationContext加载配置类


public class App3 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig3.class);
        String[] names = ctx.getBeanDefinitionNames();//定义所有bean的名字
        for (String name : names) {
            System.out.println(name);
        }  }  }


注意:使用AnnotationConfigApplicationContext加载一个配置类,这个配置类自己也会变成一个bean


扩展1——FactoryBean


初始化实现FactoryBean接口的类, 实现对bean加载到容器之前的批处理操作


public class BookFactoryBean implements FactoryBean<Book> {
  public Book getObject() throws Exception {
    Book book = new Book();
    // 造book对象之前,可以对book对象进行相关的初始化工作
    return book;//对象
}
  public Class<?> getObjectType() {
    return Book.class;//类型
} }


@ComponentScan({"com.spring.bean"})
public class SpringConfig3 {
@Bean
public BookFactoryBean book(){
  return new BookFactoryBean();
} }


扩展2——配置类中导入原始的配置文件(系统迁移)


(1)原始配置文件applicationContext-config.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          
       https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- xml方式声明自己开发的bean -->
    <bean id="cat" class="com.spring.bean.Cat"></bean>
    <bean class="com.spring.bean.Dog"></bean>
    <!--    xml方式声明第三方开发的bean-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"></bean>
</beans>


(2)使用@ImportResource注解导入


@ImportResource("applicationContext-config.xml")
public class SpringConfig2 {
}


扩展3——proxyBeanMethods


proxyBean就相当于@Configuration配置类最终出来的对象是个代理对象,Methods就是去拿创建的bean


①proxyBeanMethods=true,我们在运行对应的方法的时候,这个方法曾经在spring容器中加载过bean,再调用这个方法,

就是从容器中拿那个bean,而不再重新创建


②proxyBeanMethods=false,使用当前@Configuration配置类的对象,去执行@Bean注解下的方法,每执行一次就重新

创建一个对象


Configuration(proxyBeanMethods = false)
public class SpringConfig3 {
  @Bean
  public Book book(){
    return new Book();
} }
public class AppObject {
  public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
    SpringConfig3 config = ctx.getBean("Config", Config.class);
    config.book();
    config.book();
}


4.使用@Import导入要注入的bean


此形式可以有效解耦,实现无侵入式编程,在spring技术底层及诸多框架的整合中大量使用

(1)被导入的bean无需使用注解声明为bean

public class Dog {

}

(2)导入要注入的bean对应的字节码


@Import(Dog.class)
public class SpringConfig4 {
}


注意:这种方法生成的bean的名称是全路径类名

扩展4——使用@Import注解还可以导入配置类


@Import({Dog.class,DbConfig.class})
public class SpringConfig {
}


@Configuration
public class DbConfig {
    @Bean
    public DruidDataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        return ds;
    } }


5.使用上下文对象在容器初始化完毕后注入bean


public class AppImport {
  public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig5.class);
    ctx.register(Cat.class);
    String[] names = ctx.getBeanDefinitionNames();
    for (String name : names) {
      System.out.println(name);
} } }


6.导入实现了ImportSelector接口的类,实现对导入源的编程式处理


@Configuration
@Import(MyImportSelector.class)
public class SpringConfig6 {
}


public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
//        各种条件的判定,判定完毕后,再决定是否装载指定的bean
//       metadata指的是使用import出现的位置
//        判定SpringConfig6是否有Configuration注解
        boolean flag = metadata.hasAnnotation("org.springframework.context.annotation.Configuration");
        if (flag) {
            return new String[]{"com.spring.bean.Dog"};
        }
        return new String[]{"com.spring.bean.Cat"};
    }
}


bean的加载方式(七)


导入实现了ImportBeanDefinitionRegistrar接口的类,通过BeanDefinition的注册器注册实名bean,实现对

容器中bean的裁定,例如对现有bean的覆盖,进而达成不修改源代码的情况下更换实现的效果

和第七种方法的ImportSelector很相似,不过它把bean的管理也开启了


@Configuration
@Import(MyRegistrar.class)
public class SpringConfig7 {
}


public class MyRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
        registry.registerBeanDefinition("dog",beanDefinition);
    }
}


bean的加载方式(八)


导入实现了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);
} }
目录
相关文章
|
6月前
|
Java Spring
SpringMVC中bean的加载控制
SpringMVC中bean的加载控制
39 0
|
21天前
|
Java Shell C++
Springboot加载注入bean的方式
本文详细介绍了Spring Boot中Bean的装配方法。首先讲解了使用@Component、@Service、@Controller、@Repository等注解声明Bean的方式,并解释了这些注解之间的关系及各自适用的层次。接着介绍了通过@Configuration和@Bean注解定义Bean的方法,展示了其灵活性和定制能力。最后讨论了@Component与@Bean的区别,并提供了在Spring Boot应用中装配依赖包中Bean的三种方法:使用@ComponentScan注解扫描指定包、使用@Import注解导入特定Bean以及在spring.factories文件中配置Bean。
|
Java Spring
静态工具类注入mapper对象
项目中需要在一个utils工具类中,调用mapper对象进行查询并进行排序后选出数值最小的数值,然而静态方法里面直接注入会报空指针的错误。现在总结一下解决办法。
708 0
|
Java 数据安全/隐私保护 Spring
Spring中实例化Bean的三种方式及作用范围和生命周期
Spring中实例化Bean的三种方式及作用范围和生命周期
|
Java
Springboot加载动态Bean的10种方式
Springboot加载动态Bean的10种方式
676 0
|
Java 应用服务中间件 Maven
|
Java Spring
SpringMVC的bean的加载及控制
SpringMVC的bean的加载及控制
117 0
|
Java 容器 Spring
Spring注解(六):Bean的生命周期中自定义初始化和销毁方法的四种方式
Bean的生命周期指的是Bean从被创建到初始化再被销毁的过程,IOC容器管理Bean的生命周期。在Bean的整个生命周期的过程中的初始化和销毁过程的方法可以被自定义,IOC容器当Bean进行到当前生命周期的时候调用自定义的初始化和销毁方法。在配置文件中可以通过添加init-method和destroy-method指定自定义的初始化和销毁方法
782 0
Spring注解(六):Bean的生命周期中自定义初始化和销毁方法的四种方式
|
Java Spring 容器
Spring解析,加载及实例化Bean的顺序(零配置)
在A之前实例化好。很多时候Spring智能地为我们做好了这些工作,但某些情况下可能不是,比如Springboot的@AutoConfigureAfter注解,
Spring解析,加载及实例化Bean的顺序(零配置)