zoukankan      html  css  js  c++  java
  • Spring IOC 理解

           本文在参考资料的基础上进行阐述的,部分内容来自参考文章。

            要了解控制反转( Inversion of Control ), 我觉得有必要先了解软件设计的一个重要思想:依赖倒置原则(Dependency Inversion Principle )

            假如我们现在需要造一辆车,所需要的依赖关系如下:

    捕获

            用代码来表示就是

    v2-8ec294de7d0f9013788e3fb5c76069ef_hd

           上面车的轮子尺寸都是 size = 30 , 现在希望轮子的尺寸可以是动态,那么修改代码如下,

    v2-64e8b19eeb70d9cf87c27fe4c5c0fc81_hd

            相应的 car 的代码修改如下 ,

    v2-82e0c12a1b26f7979ed9241e169affda_hd

               可以看到这样我们需要自底而上去修改每个类,这样的代码是糟糕的,而且很难维护, 这时我们需要控制反转( ioc ), 及上层控制下层,而不是下层控制着上层。我们用依赖注入(Dependency Injection)这种方式来实现控制反转。所谓依赖注入,就是把底层类作为参数传入上层类,实现上层类对下层类的“控制”。

                那么到底依赖注入和控制反转到底是什么关系?

    v2-ee924f8693cff51785ad6637ac5b21c1_hd

             依赖倒置是原则,为了贯彻这个原则,确定控制(ioc )的思路,运用依赖注入的方法, 第三方容器在后面讲。

             OK,现在知道了问题所在,如何解决呢?如何运用上依赖注入(DI)方法呢? 一般来说,依赖注入有三种方法, 构造方法注入,定义为接口,setting 方法注入, 其中setting方法和构造很相似,也很好理解,定义为接口,好处很明显,只要继承接口, 那么最终实现类就可以用很多,我们下面使用构造方法实现依赖注入看看。

    v2-99ad2cd809fcb86dd791ff7f65fb1779_hd

          这种设计模式还有利于不同组的协同合作和单元测试:比如开发这四个类的分别是四个不同的组,那么只要定义好了接口,四个不同的组可以同时进行开发而不相互受限制;而对于单元测试,如果我们要写Car类的单元测试,就只需要Mock一下Framework类传入Car就行了,而不用把Framework, Bottom, Tire全部new一遍再来构造Car。

    作者:Sevenvidia
    链接:https://www.zhihu.com/question/23277575/answer/169698662
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

             问题解决了,很好,刚才那张图不是还有个容器的东西吗,依赖注入容器到底是什么呢?以上面的例子,将创建对象的地方封装成一个容器,请看

             v2-c845802f9187953ed576e0555f76da42_hd

             还是生产这个 Car , 经过依赖注入容器的方法的有是怎么样的呢?

          v2-5ca61395f37cef73c7bbe7808f9ea219_hd

              我们再回想一下Spring ,看一下下图代码

      1 @Configuration
      2 @EnableCaching
      3     public class RedisConfiguration extends CachingConfigurerSupport {
      4 
      5     private static Logger logger = LoggerFactory.getLogger(RedisConfiguration.class);
      6 
      7 
      8     @Autowired
      9     private JedisConnectionFactory jedisConnectionFactory;
     10 
     11 
     12     //缓存管理器
     13     @Bean
     14     public RedisCacheManager cacheManager(JedisConnectionFactory jedisConnectionFactory) {
     15         return RedisCacheManager.create(jedisConnectionFactory);
     16     }
     17 
     18     @Bean
     19     public StringRedisTemplate getRedisTemplate(){
     20         StringRedisTemplate template = new StringRedisTemplate();
     21         template.setConnectionFactory(jedisConnectionFactory);
     22         return template;
     23     }
     24  }

           代码中的 JedisConnectFactory

      1 @PropertySource("classpath:application.properties")
      2 @Configuration
      3 public class JedisRedisConfig  {
      4     @Value("${spring.redis.host}")
      5     private String host;
      6     @Value("${spring.redis.port}")
      7     private int port;
      8     @Value("${spring.redis.password}")
      9     public String password;
     10     @Value("${spring.redis.jedis.pool.max-active}")
     11     private int maxActive;
     12     @Value("${spring.redis.jedis.pool.max-wait}")
     13     private long maxWaitMillis;
     14     @Value("${spring.redis.timeout}")
     15     private  int timeout;
     16 
     17 
     18     @Bean
     19     JedisConnectionFactory jedisConnectionFactory() {
     20         RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(host, port);
     21         JedisConnectionFactory factory = new JedisConnectionFactory(configuration);
     22         return factory;
     23     }
     24 
     25     @Bean
     26     public JedisPool redisPoolFactory() {
     27         JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
     28         jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
     29         JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
     30         return jedisPool;
     31     }
     32 
     33 
     34 }

             第一段代码中,JedisConfiguration 类就可以拿来用了,等一下, JedisConnectFactory 还没实例化呢,只是在第二段代码中有返回一个也是 JedisConnectFactory ,实际上Spring 就是使用这个容器为我们储存了对象,当我需要使用时直接拿出来用就行了。

    参考资料:

    1.Spring IoC有什么好处呢?

  • 相关阅读:
    第十一篇 中间件
    第十篇 Form表单
    第九篇 AJAX
    第八篇Django分页
    第七篇 Django-认证系统
    第五篇Django URL name 详解
    第四篇Django之模板语言
    java_tomcat_Server at localhost was unable to start within 45 seconds 小喵咪死活启动报错-二
    java_tomcat_the_APR based Apache Tomcat 小喵咪死活启动报错_临时方案
    linux_设置开机自启动程序脚本
  • 原文地址:https://www.cnblogs.com/Benjious/p/9296701.html
Copyright © 2011-2022 走看看