(一)程序的耦合
- 耦合:程序间 的依赖关系
类之间的依赖
方法之间的依赖 - 解耦:降低耦合度
解耦的思路:
1.是利用反射来创建对象,避免使用new;如:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName(“com.mysql.jdbc.Driver”);
2.通过读取配置文件来读取全限定类名xml/properties等
为什么要放在配置文件?中,不如说数据库连接驱动就要经常替换,那样比较方便
实例:
BeanFactory.java
package com.lc.factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
一个创建Bean对象的工厂: * 工厂模式
*/
public class BeanFactory {
// 定义一个properties对象
private static Properties props;
// 静态加载类容
static {
try {
// 实例化
props = new Properties();
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
} catch (IOException e) {
throw new ExceptionInInitializerError("初始化读取bean.properties失败");
}
}
public static Object getBean(String beanName){
Object bean = null;
try {
String beanPath = props.getProperty(beanName);
bean = Class.forName(beanPath).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return bean;
}
}
被解耦对象
package com.lc.ui;
// An highlighted block
import com.lc.factory.BeanFactory;
import com.lc.service.IAccountService;
import com.lc.service.impl.IAccountServiceImpl;
public class Client {
public static void main(String[] args) {
// 被解耦对象
//IAccountService iAccountService = new IAccountServiceImpl();
IAccountService iAccountService = (IAccountService) BeanFactory.getBean("accountService");
iAccountService.saveAccount();
}
}
*BeanFactory单例改造
// Acode block
package com.lc.factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* 一个创建Bean对象的工厂
*/
public class BeanFactory {
// 定义一个properties对象
private static Properties props;
// 定义一个对象来存放容器
private static Map<String, Object> beans;
// 静态加载类容
static {
try {
// 实例化
props = new Properties();
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
// 初始化容器
beans = new HashMap<>();
Enumeration<Object> keys = props.keys();
while (keys.hasMoreElements()){
// 存储到容器
String key = keys.nextElement().toString();
String beanPath = props.getProperty(key);
// 反射创建对象
Object value = Class.forName(beanPath).newInstance();
beans.put(key, value);
}
} catch (Exception e) {
throw new ExceptionInInitializerError("初始化读取bean.properties失败");
}
}
public static Object getBean(String beanName){
return beans.get(beanName);
}
}
应该做到编译时不依赖,运行时才依赖
(二)spring Ioc
削减程序耦合,并不能完全消除耦合
导包
配置文件:名字任意(非中文
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLotion="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--把对象创建交给beanFactory-->
<bean id="accountService" class="com.lc.service.impl.IAccountServiceImpl"></bean>
<bean id="accountDao" class="com.lc.dao.impl.IAccountDaoImpl"></bean>
</beans>
创建对象
// 获取核心容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountService iAccountService = ac.getBean("accountService", IAccountService.class);
核心容器两个接口引发的问题:
- ApplicationContext::他在构建核心容器时,创建对象采用的是以及加载的策略,只要一读取配置文件就创建
- BeanFactory: 他在构建核心容器的时候 创建对象采取的是延迟加载的策略,什么时候根据id获取对象,什么时候创建对象
(三)spring 创建bean的管理细节
spring 创建bean的管理细节:
1.创建bean 的三种方式
<!--1.创建bean 的三种方式-->
<!--第一种方式使用默认构造函数创建 bean标签,使用无参构造函数-->
<!-- <bean id="accountService" class="com.lc.service.impl.IAccountServiceImpl"></bean>-->
<!--第二种使用某个类中的方法来创建对象-->
<!--<bean id="instanceFactory" class="com.lc.factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>-->
<!--第三种使用工厂中的静态方法来创建对象-->
<bean id="accountService" class="com.lc.factory.StaticFactory" factory-method="getAccountService"></bean>
2.bean对象的作用范围调整:
<!--2.bean对象的作用范围调整:
scope属性:singleton -> 单例(默认)
prototype -> 多例
request -> 作用于web应用的请求范围
session -> 作用于web应用的会划范围
global-session ->作用于集群环境的回话范围,当不是集群环境时它就是session
-->
<bean id="accountService" class="com.lc.service.impl.IAccountServiceImpl" scope="prototype"></bean>
3.bean对象的生命周期
<bean id="accountService" class="com.lc.service.impl.IAccountServiceImpl" init-method="init" destroy-method="destory"></bean>
(四)依赖注入
依赖注入:dependence Injection
IOC 作用:降低程序间的耦合(依赖关系)
依赖关系管理:以后都交给spring来维护我们只需要在配置文件中说明依赖关系的维护:就称之为依赖注入
能注入的数据有三类:
基本类型和String
其他bean类型(在配置文件或者注解中配置过的bean)
复杂类型(集合类型)
注入的方式:有三种
第一种:使用构造函数
第二种:使用set方法
第三种:使用注解提供
1.使用构造函数注入
<!--第一种:使用构造函数-->
<bean id="accountService" class="com.lc.service.impl.IAccountServiceImpl">
<constructor-arg name="name" value="test"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<!--配置一个日起对象-->
<bean id="now" class="java.util.Date"></bean>
1.set注入
<!--配置一个日起对象-->
<bean id="now" class="java.util.Date"></bean>
<!--第二种:使用set注入-->
<bean id="accountService2" class="com.lc.service.impl.IAccountServiceImpl2">
<property name="name" value="Test2"></property>
<property name="age" value="18"></property>
<property name="birthday" ref="now"></property>
</bean>
- 复杂类型注入
package helloworld;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class User {
private List list;
private Map<String, String> map;
private Properties pro;
public void setList(List list) {
this.list = list;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setPro(Properties pro) {
this.pro = pro;
}
public void say() {
System.out.println(list);
System.out.println(map);
System.out.println(pro);
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:contexnt="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="user" class="helloworld.User">
<property name="list">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
<property name="map">
<map>
<entry key="a" value="apple"></entry>
<entry key="b" value="banner"></entry>
</map>
</property>
<property name="pro">
<props>
<prop key="name">Tom</prop>
<prop key="age">25</prop>
</props>
</property>
</bean>