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有什么好处呢?

猜你喜欢

转载自www.cnblogs.com/Benjious/p/9296701.html
今日推荐