zoukankan      html  css  js  c++  java
  • Springboot依赖注入笔记

    结合Autowired和Service注解

    public interface IUser {
        void say();
    }
    
    @Service
    public class Student implements IUser {
    
        @Override
        public void say() {
            System.out.println("I'm a student");
        }
    }
    
    @Component
    @Order(value = 3)
    public class Entry implements CommandLineRunner {
        public Log log = LogFactory.getLog(Entry.class);
    
        @Autowired
        IUser user;
    
        @Override
        public void run(String... args) throws Exception {
            user.say();
        }
    }

    如果要在构造函数中就需要访问注入的变量,那么Autowired的位置就要放到构造函数上

    @Component
    @Order(value = 3)
    public class TestService {
        private final IUser user;
    
        @Autowired
        public void TestService (IUser user) {
            user.say();
        }
    }

    自定义注入的扫描范围

    要注意Springboot扫描包的时候默认是从启动类(一般是Application)目录开始往下扫描,也就意味着如果Bean不在Application目录的下层,是不会被扫描到的。

    这种情况会提示:

    Description:
    Field xxx in xxxxxx required a bean of type 'xxxxxx' that could not be found.
    
    Action:
    Consider defining a bean of type 'xxxxxxxxxxxxxx' in your configuration.

    不过这也不是无法改变的,我们手动指定扫描范围即可:

    @SpringBootApplication
    @ComponentScan(basePackages={"springbootdemo.basic","anotherspringbootdemo.basic"})
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }

    范围列表中不要忘记添加原来的目录,及启动类的包范围。

    另外,这个ComponentScan不是必须放到启动类上,只要可以被扫描到即可。

    通过Configuration的方式

    通过Configuration也可以实现“跨域”的注入方式(即package不在一个范围内)

    /**
    * Springboot会扫描标有Configuration注解的类
    * 该类中标有Bean注解的方法,返回值会被作为被注入项
    * 至于这个Bean的注入项,在方法里面return就是。
    */
    @Configuration
    public class TestConfig{
        
        @Bean
        public IUser user(){
            return new Teacher();
        }
    
        //有依赖关系的Bean也很简单
        //这个IDepartment依赖IUser
        @Bean
        public IDepartment(){
            return new Development(user());
        } 
    }
    
    /*调用*/
    public class TestClass{
    
        @Autowired
        IUser user;
        
        public void run(String... args) throws Exception {
            user.say();
        }
    }

    上面的Configuration虽然解决了“跨域”注入,但Configuration注解还是要求放到调用的项目中。

    很多时候当我们需要依赖一个第三方jar包,并想要实现自动注入的时候,我们并不想再去手动写Configuration,毕竟如果多个地方引用这个jar包,每一处都需要这样处理。

    能不能一劳永逸呢?

    使用Springboot中的框架时,例如使用ES,我们发现虽然并没有声明ElasticSearchTemplate,但是却可以直接使用

    这里有一篇不错的讲解 https://www.jianshu.com/p/346cac67bfcc

    假设第三方项目是ProjectA,应用方是ProjectB

     现在ProjectA有 类TestTemplate

    package ProjectA;
    
    public class TestTemplate{
    
        public void test() {
            System.out.println("GO TEST");
        }
    }

    ProjectB需要注入并使用TestTemplate,当然肯定要先添加maven的依赖(忽略),调用逻辑

    package ProjectB;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.stereotype.Component;
    import springbootdemo.common.TestTemplate;
    
    @Component
    public class Entry implements CommandLineRunner {
        
        @Autowired
        private TestTemplate aa;
    
        @Override
        public void run(String... args) throws Exception {
            aa.test();
        }
    }

    这时候运行ProjectB的话肯定是会报错的,因为找不到TestTemplate的注入结果,即使在TestTemplate上添加注解也是一样。

    我们直接给出一个简单的解决方案

    ①在ProjectA中新建一个自动配置类 TestAutoConfiguration

    package ProjectA;
    
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class TestAutoConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public TestTemplate testTemplate(){
            return new TestTemplate();
        }
    }

    ②在ProjectA的资源目录src/main/resources下创建目录META-INF/spring.factories

     

    内容:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    ProjectA.TestAutoConfiguration

    现在再执行,一切OK!

  • 相关阅读:
    Web 安全 —— XSS攻击的原理
    HTTP缓存
    JavaScript 事件循环机制(Event Loop)
    搭建前端监控系统
    电脑 直接下载cyida deb
    基于样例的传统图像修补算法实现
    Android WorkManager 定时任务
    Android WorkManager工作约束,延迟与查询工作
    微信小程序地图如何显示附近厕所WC步行路线
    物流解决方案再添利器 腾讯位置服务推出货运“三件套”
  • 原文地址:https://www.cnblogs.com/TiestoRay/p/8891469.html
Copyright © 2011-2022 走看看