Spring容器注入bean的方法有哪些

开发技术 作者:iii 2024-04-22 21:10:01
本文小编为大家详细介绍“Spring容器注入bean的方法有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring容器注入bean的方法有哪些”文章能帮助大家解...

本文小编为大家详细介绍“Spring容器注入bean的方法有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring容器注入bean的方法有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    @ComponentScan+@Component

      @ComponentScan可以放在启动类上,指定要扫描的包路径;该包路径下被@Component修饰的类,都会被注入到Spring容器中。

    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.ComponentScan;
    @ComponentScan(basePackages = "com.gs.beanRegister")
    public class BootStrap {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(BootStrap.class);
            A bean = context.getBean(A.class);
            bean.say();
        }
    }

      com.gs.beanRegister包下:

    import org.springframework.stereotype.Component;
    @Component
    public class A {
        public void say() {
            System.out.println("这是a");
        }
    }

      注:在SpringBoot中,由于其自动装配的特性,所以@ComponentScan可以不加,只要@Component修饰的类和启动类在同一包下或者在启动类所在包的子包下。

    @Configuration+@Bean

      @Configuration用来声明一个配置类,如果它的方法被@Bean修饰,那么该方法返回的对象也会被注入到Spring容器中。

      代码方面,BootStrap 类不动,A类的@Component去掉,com.gs.beanRegister包下建个配置类:

    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Bean;
    @Configuration
    public class MyConfiguration {
        @Bean
        public A a() {
            return new A();
        }
    }

    通过@Import注解

      这个注解可能平时大家接触得不多,它有好几种使用方式。

    1.直接导入类的class

    import org.springframework.context.annotation.Import;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    @Import(A.class)
    public class BootStrap {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(BootStrap.class);
            A bean = context.getBean(A.class);
            //B bean = context.getBean(B.class);
            bean.say();
        }
    }

      A类不用添加任何注解:

    public class A {
        public void say() {
            System.out.println("这是a");
        }
    }

    2.导入配置类

    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Import;
    @Import(MyConfiguration.class)
    public class BootStrap {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(BootStrap.class);
            A bean = context.getBean(A.class);
            bean.say();
        }
    }
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    // 使用@Import导入配置类时,@Configuration可以不加
    //@Configuration
    public class MyConfiguration {
        @Bean
        public A a() {
            return new A();
        }
    }

    3.导入ImportSelector的实现类

    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Import;
    @Import(MyImportSelector.class)
    public class BootStrap {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(BootStrap.class);
            A bean = context.getBean(A.class);
            bean.say();
        }
    }
    import org.springframework.context.annotation.ImportSelector;
    import org.springframework.core.type.AnnotationMetadata;
    public class MyImportSelector implements ImportSelector {
        @Override
        public String[] selectImports(AnnotationMetadata metadata) {
            // 返回要注入的bean的全路径,A类不用任何注解修饰
            // SpringBoot的自动装配,就用到了这种方式:
            // 返回配置类的全路径,配置类的@Bean方法返回的对象也能注入到容器中
            return new String[] { A.class.getName() };
        }
    }

    4.导入ImportBeanDefinitionRegistrar的实现类

    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Import;
    @Import(MyImportBeanDefinitionRegistrar.class)
    public class BootStrap {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(BootStrap.class);
            A bean = context.getBean(A.class);
            bean.say();
        }
    }
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.RootBeanDefinition;
    import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
    import org.springframework.core.type.AnnotationMetadata;
    public class MyImportBeanDefinitionRegistrar implements 
                 ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata metadata, 
                    BeanDefinitionRegistry registry) {
            // 构建bean的元数据,A类不用任何注解修饰
            // spring-mybatis扫描mapper接口,生成代理类,就是用的这种方式
            BeanDefinition definition = new RootBeanDefinition(A.class);
            registry.registerBeanDefinition("a", definition);
        }
    }

    借助FactoryBean接口

      实现FactoryBean接口的类,除了本身会被注入外,getObject方法返回的对象也会被注入到Spring容器中。

    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Import;
    @Import(MyFactoryBean.class)
    public class BootStrap {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(BootStrap.class);
            A bean = context.getBean(A.class);
            bean.say();
        }
    }
    import org.springframework.beans.factory.FactoryBean;
    public class MyFactoryBean implements FactoryBean {
        @Override
        public Object getObject() throws Exception {
            return new A();
        }
        @Override
        public Class<?> getObjectType() {
            return A.class;
        }
    }

    借助BeanDefinitionRegistryPostProcessor接口

    &emsp;&emsp;在Spring容器启动时,会调用该接口的postProcessBeanDefinitionRegistry方法,大概意思是等BeanDefinition(上面提到的bean的元数据)加载完成后,再对它进行后置处理。所以可以在此调整BeanDefinition,从而把对应的bean注入。

    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    public class BootStrap {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext();
            BeanDefinitionRegistryPostProcessor postProcessor = 
            new MyBeanDefinitionRegistryPostProcessor();
            context.addBeanFactoryPostProcessor(postProcessor);
            context.refresh();
            A a = context.getBean(A.class);
            a.say();
        }
    }
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    import org.springframework.beans.factory.support.RootBeanDefinition;
    public class MyBeanDefinitionRegistryPostProcessor implements 
                 BeanDefinitionRegistryPostProcessor {
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry 
                    registry) throws BeansException {
            BeanDefinition definition = new RootBeanDefinition(A.class);
            registry.registerBeanDefinition("a", definition);
        }
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory 
                    beanFactory) throws BeansException {
        }
    }

    读到这里,这篇“Spring容器注入bean的方法有哪些”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注捷杰建站行业资讯频道。

    原创声明
    本站部分文章基于互联网的整理,我们会把真正“有用/优质”的文章整理提供给各位开发者。本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
    本文链接:http://www.jiecseo.com/news/show_16010.html
    spring bean