什么是依赖注入?依赖注入本人的通俗理解就是类和类之间的关系不是通过硬编码的方式构建,而是通过配置,由第三方模块来帮助构建,带来的好处就是减少了侵入式编程,实现了类的高内聚和低耦合。
Spring如何提供了依赖注入?Spring容器将注册在其内的类的对象都看作一个个相互独立的Spring Bean,一个个Spring Bean实际上就是一个个POJO,开发者只要专注于开发好手头的类,然后通过Spring提供的各种装配机制,将这些Spring Bean联系在一起,构成一定的依赖关系即可。带来的好处就是,依赖关系完全独立于主代码逻辑,既方便我们修改类,也方便我们添加类。
下面举一个例子,来看看如何运用Spring的装配机制来实现依赖注入。这个例子很简单,主要为了看看Spring依赖注入的威力,例子是电脑和鼠标的例子,有一台电脑,需要使用鼠标,鼠标提供了左键和右键,有不同的颜色的两个鼠标。基于Spring建议的面向接口编程,我们先看看我们的鼠标接口
package com.yjp.spring.study.beans; public interface Mouse { void clickLeft(); void clickRight(); }
这是一个很简陋的鼠标,只能点击左键和右键。然后看看我们的电脑类,也够简陋的
package com.yjp.spring.study.beans; public class Computer { private Mouse mouse; public Computer(Mouse mouse) { this.mouse = mouse; } public void selectAnIcon() { mouse.clickLeft(); } public void contextMenu() { mouse.clickRight(); } }
我们的电脑持有一个鼠标接口,这让我们不必关心具体的鼠标,只要有点击左键和右键的功能就行,电脑可以选择一个图标,点击鼠标左键即可,也可以弹出右键菜单,点击鼠标右键即可。下面再看看我们两款简陋的鼠标,先看看白鼠
public class WhiteMouse implements Mouse { public void clickLeft() { System.out.println("WhiteMouse Left Clicked!"); } public void clickRight() { System.out.println("WhiteMouse Right Clicked!"); } }
再看看黑鼠
package com.yjp.spring.study.beans; public class BlackMouse implements Mouse { public void clickLeft() { System.out.println("BlackMouse Left Clicked!"); } public void clickRight() { System.out.println("BlackMouse Right Clicked!"); } }
都很简单,现在,我们完成了鼠标类和键盘类,但是他们之间没有联系,唯一的联系只有Computer有个鼠标接口,可以让鼠标接入。下面就是Spring发挥作用的时候了,我们先按照自动装配的方式对他们进行装配。
首先,创建一个配置类。并在配置类上加上注解
package com.yjp.spring.study.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan({"com.yjp.spring.study.beans"}) public class ComputerConfig { }
@Configuration注解说明该类是一个配置类,@ComponentScan则开启了自动扫描,Spring容器会自动扫描指定包下加上@Component的类,为其创建bean,默认的bean id为类名第一个字母小写。
在Computer类上加上注解
@Component public class Computer { ...... @Autowired public Computer(Mouse mouse) { this.mouse = mouse; } ...... }
@Component表示Computer是一个Spring Bean,Spring容器扫描后会创建bean id为computer的bean,@Autowired表示要为方法的参数mouse执行自动装配,会以Mouse类型的bean自动装配mouse。
WhiteMouse类只需要在类声明上加上注解即可,不存在需要自动装配的内容
@Component public class WhiteMouse implements Mouse {
然后实现我们的Demo,如下
package com.yjp.spring.study; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import com.yjp.spring.study.beans.Computer; public class TestComputer { public static void main(String[] args) { AbstractApplicationContext context = new AnnotationConfigApplicationContext( com.yjp.spring.study.config.ComputerConfig.class); Computer computer = context.getBean(Computer.class); computer.selectAnIcon(); computer.contextMenu(); context.close(); } }
基于配置类,创建一个ApplicationContext,然后调用getBean拿到一个Computer的实例,调用方法,运行可以看到对应的打印,执行正常。
但是,现在有一个问题,如果我们对上面的BlackMouse同样添加@Component,则会出现问题,原因是WhiteMouse和BlackMouse都实现了Mouse接口,那就意味着在自动装配Computer中的mouse时,Spring无法区分该使用哪个实现了Mouse的bean。那该如何处理呢?
大体上有两种方法,为了叙述方便,先说第一种,我们继续给BlackMouse添加注解,但是这次,要多添加一条
@Component @Primary public class BlackMouse implements Mouse {
多了一条@Primary,这就告诉Spring容器,将blackMouse这个id的bean作为首选bean进行装配,也就是发生冲突不知道装配哪一个的时候就用它。现在运行程序,打印将变为调用BlackMouse的内容。
现在,再说一下第二种解决冲突的方法,先移除上面的@Promary注解。
@Component public class BlackMouse implements Mouse
然后,修改Computer的构造函数
@Autowired public Computer(@Qualifier("blackMouse") Mouse mouse) { this.mouse = mouse; }
可以看到,在mouse参数前,加入了@Qualifier注解,使用@Qualifier("beanId")注解,可以显示说明要使用beanId的bean进行装配。
上面就是Spring进行装配的过程,可以看到,后面的装配阶段,我们没有修改过任何代码,,也没有显式的new出Mouse然后赋值,只是通过注解就完成了所有关联工作。
转载自:http://blog.csdn.net/yjp19871013/article/details/53537398
Java Socket编程(二) 几种常见的服务器模型
http://wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=502
Java Socket编程(三) 并发服务器
http://wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=503
Java Socket编程(四) 异步服务器
http://wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=504