Spring
IOC/DI
DI的优势:解耦
紧耦合:软件组件之间是紧密依赖,很难拆分
松耦合:软件组件之间是松散依赖,随时可以更换
解耦:将软件组件从紧耦合转换为松耦合关系
IOC、DI
利用Spring管理光头强和工具之间的依赖关系
1.创建工具接口
/**
* 工具接口
*/
public interface Tool {
}
2.创建具体的工具:斧子
public class Axe implements Tool,Serializable {
@Override
public String toString() {
return "斧子";
}
}
3.创建具体的工具:电锯
public class Saw implements Tool ,Serializable{
@Override
public String toString() {
return "电锯";
}
}
4.创建工人类型
public class Worker implements Serializable {
private String name;//基本值
private Tool tool;//Bean对象
private int age;//基本值
public Worker() {
this.name = "光头强";
}
public Worker(String name) {
this.name = name;
}
public void work() {
System.out.println(name + "使用" + tool + "砍树");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("setName:" + name);
this.name = name;
}
public Tool getTool() {
return tool;
}
public void setTool(Tool tool) {
this.tool = tool;
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("setAge:" + age);
this.age = age;
}
@Override
public String toString() {
return "Worker [name=" + name + ", tool=" + tool + "]";
}
}
5.在Spring配置文件中利用IOC/DI解决依赖关系
<!-- 控制反转IOC,由Spring创建对象称为控制反转 -->
<bean id="axe" class="spring.Axe" />
<bean id="saw" class="spring.Saw" />
<bean id="qiang" class="spring.Worker">
<!-- 依赖注入DI:由Spring帮忙建立对象的依赖关系 -->
<!-- Spring会自动调用setTool方法注入axe引用 -->
<property name="tool" ref="axe" />
</bean>
6.创建测试案例
public class TestCase {
ClassPathXmlApplicationContext ctx;
@Before
public void init() {
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void testQiang() {
Worker qiang = ctx.getBean("qiang",Worker.class);
qiang.work();
}
@After
public void destroy() {
ctx.close();
}
}
构造器参数注入
Spring支持 利用 构造器创建对象:constructor-arg 子元素,其中index="0"用于指定参数在构造器参数的位置。
1.配置
<bean id="xiaoqiang" class="spring.Worker">
<!-- 构造器参数注入 也就是调用有参构造器创建对象 -->
<constructor-arg index="0" value="光头不强"/>
<property name="tool" ref="saw" />
</bean>
2.测试
@Test
public void testXiaoQiang() {
Worker xiaoqiang = ctx.getBean("xiaoqiang", Worker.class);
xiaoqiang.work();
}
按照名字自动注入
Spring支持自动按照名字注入功能,Spring会自动检查Bean属性和Bean ID的匹配,如果匹配上就自动完成注入
优点:自动注入可以减少XML文件的编写量
1.配置文件
<bean id="tool" class="spring.Axe" />
<!-- autowire="byName" 自动按照Bean属性名字和id的值的对应关系自动注入 实现按照名字自动装配 -->
<bean id="tom" class="spring.Worker" autowire="byName">
<constructor-arg index="0" value="Tom"/>
</bean>
2.测试案例
@Test
public void testTom() {
Worker tom = ctx.getBean("tom",Worker.class);
tom.work();
}
按照类型自动注入
1.创建新的配置文件applicationContext1.xml
<bean class="spring.Axe" />
<!-- autowire="byType" 实现按照类型自动装配 -->
<bean id="tom" class="spring.Worker" autowire="byType" />
2.测试案例
public class TestCase2 {
ClassPathXmlApplicationContext ctx;
@Before
public void init() {
ctx = new ClassPathXmlApplicationContext("applicationContext2.xml");
}
@Test
public void testTom() {
Worker tom = ctx.getBean("tom",Worker.class);
tom.work();
}
@After
public void destroy() {
ctx.close();
}
}
基本值注入
Spring支持为Bean注入基本类型参数,包括8个基本数据类型,8个包装类型,String类型
注入基本值时,会调用Bean属性的set方法实现
1.配置
<!-- 测试基本值的注入基本值包含:8个基本类型 8个包装类 String类型 -->
<bean id="jerry" class="spring.Worker">
<property name="tool" ref="axe" />
<!-- 注解基本值,使用value属性 -->
<property name="name" value="Jerry" />
<property name="age" value="10" />
</bean>
2.Worker类
public class Worker implements Serializable {
private String name;//基本值
private Tool tool;//Bean对象
private int age;//基本值
public Worker() {
this.name = "光头强";
}
public Worker(String name) {
this.name = name;
}
public void work() {
System.out.println(name + "使用" + tool + "砍树");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("setName:" + name);
this.name = name;
}
public Tool getTool() {
return tool;
}
public void setTool(Tool tool) {
this.tool = tool;
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("setAge:" + age);
this.age = age;
}
@Override
public String toString() {
return "Worker [name=" + name + ", tool=" + tool + "]";
}
}
3.测试案例
@Test
public void testJerry() {
Worker jerry = ctx.getBean("jerry",Worker.class);
jerry.work();
}
利用Spring配置数据源
1.下载DBCP及JDBC依赖
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
2.配置文件
<!-- 利用Spring 创建 DataSource 连接池实例 -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="maxActive" value="10"/>
<property name="initialSize" value="2"/>
</bean>
3.测试案例
public void testDataSource() throws SQLException {
//BasicDataSource实现了DataSource接口
DataSource ds = ctx.getBean("dataSource",DataSource.class);
System.out.println(ds);
Connection conn = ds.getConnection();
String sql = "select 'HelloWorld!' as str";
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery(sql);
while(rs.next()) {
System.out.println(rs.getString("str"));
}
rs.close();
stat.close();
conn.close();
}
Spring集合注入
1.Worker类属性新增集合
private List<Tool> tools;//注入集合
public List<Tool> getTools() {
return tools;
}
public void setTools(List<Tool> tools) {
this.tools = tools;
}
2.配置文件
<!-- 为Bean对象注入集合 -->
<bean id="john" class="spring.Worker">
<!-- Bean对象注入 -->
<property name="tool" ref="axe"/>
<!-- 基本值注入 -->
<property name="name" value="大表哥"/>
<!-- List集合注入 -->
<property name="tools" >
<list>
<bean class="spring.Axe"/>
<bean class="spring.Saw"/>
<bean class="spring.Axe"/>
<bean class="spring.Saw"/>
</list>
</property>
</bean>
3.测试案例
@Test
public void testJohn() {
Worker john = ctx.getBean("john",Worker.class);
System.out.println(john.getTools());
}
Spring读取Properties文件
1.在resource文件夹下创建jdbc.properties文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb
username=root
password=root
maxActive=10
initialSize=2
2.配置文件
<util:properties id="jdbc" location="classpath:jdbc.properties"/>
3.测试案例
@Test
public void testProperties() {
Properties cfg = ctx.getBean("jdbc",Properties.class);
System.out.println(cfg);
}
Spring表达式
与EL表达式类似
Spring表达式也可以读取
1.bean属性:#{qiang.name} #{qiang['name']}
2.数组元素:#{arr[0]}
3.集合元素:#{list[1]}
4.Map(Properties)元素:#{jdbc.username} #{jdbc['username']}
在Spring文件中,可以利用Spring表达式,将一个Bean对象的属性,赋值给另外一个Bean
使用Spring表达式配置数据源
1.配置文件
<util:properties id="jdbc" location="classpath:jdbc.properties"/>
<!-- 利用Spring创建DataSource连接池实例 -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="#{jdbc.driver}" />
<property name="url" value="#{jdbc.url}" />
<property name="username" value="#{jdbc.username}" />
<property name="password" value="#{jdbc.password}" />
<property name="maxActive" value="#{jdbc.maxActive}" />
<property name="initialSize" value="#{jdbc.initialSize}" />
</bean>
2.测试案例
@Test
public void testProperties() {
Properties cfg = ctx.getBean("jdbc",Properties.class);
System.out.println(cfg);
}