• Bean的加载方式


    1.XML方式声明bean

    
    <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 id="bookService" class="com.itheima.service.impl.BookServiceImpl"/>
    	
    	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.XML+注解方式声明bean

    
    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    @Service
    public class BookServiceImpl implements BookService {
    }
    
    • 1
    • 2
    • 3

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

    @Configuration
    public class DbConfig {
    	@Bean
    	public DruidDataSource getDataSource(){
    		DruidDataSource ds = new DruidDataSource();
    		return ds;
    } }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (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;
    } }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (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);
            }  }  }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意:使用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;//类型
    } }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    @ComponentScan({"com.spring.bean"})
    public class SpringConfig3 {
    @Bean
    public BookFactoryBean book(){
    	return new BookFactoryBean();
    } }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    (1)原始配置文件applicationContext-config.xml

    
    <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">
        
        <bean id="cat" class="com.spring.bean.Cat">bean>
        <bean class="com.spring.bean.Dog">bean>
        
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    (2)使用@ImportResource注解导入

    @ImportResource("applicationContext-config.xml")
    public class SpringConfig2 {
    }
    
    • 1
    • 2
    • 3

    扩展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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

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

    (1)被导入的bean无需使用注解声明为bean
    public class Dog {
    }
    (2)导入要注入的bean对应的字节码

    @Import(Dog.class)
    public class SpringConfig4 {
    }
    
    • 1
    • 2
    • 3

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

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

    @Import({Dog.class,DbConfig.class})
    public class SpringConfig {
    }
    
    • 1
    • 2
    • 3
    @Configuration
    public class DbConfig {
        @Bean
        public DruidDataSource dataSource(){
            DruidDataSource ds = new DruidDataSource();
            return ds;
        } }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    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);
    } } }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    @Configuration
    @Import(MyImportSelector.class)
    public class SpringConfig6 {
    }
    
    • 1
    • 2
    • 3
    • 4
    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"};
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    7.bean的加载方式(七)

    导入实现了ImportBeanDefinitionRegistrar接口的类,通过BeanDefinition的注册器注册实名bean,实现对容器中bean的管理,例如设置bean为单例,进而达成不修改源代码的情况下更换实现的效果和第七种方法的ImportSelector很相似,不过它把bean的管理也开启了

    @Configuration
    @Import(MyRegistrar.class)
    public class SpringConfig7 {
    }
    
    • 1
    • 2
    • 3
    • 4
    public class MyRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
            registry.registerBeanDefinition("dog",beanDefinition);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    8.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);
    } }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    ElasticSearch RestHighLevClient 之聚合操作
    Excel函数
    Hbase学习日记:四、Hbase架构
    java读取配置文件工具类
    js模块 - amd cmd commonjs esm umd
    MySQL-笔记-07.试图及索引的应用
    【软件推荐】我的常用Windows软件
    端口安全、MAC地址漂移、MACsec、流量控制、DHCP snooping
    【C++进阶】继承
    电脑有自带的录屏功能吗win7
  • 原文地址:https://blog.csdn.net/y516369/article/details/127588167