Spring框架学习日志(1/4)
Spring框架第一天
1、Spring概述
-
学习的是冰山一角:SpringFramework
-
两大核心:IOC AOP
-
Spring5.0
-
优势:方便解耦,简化开发;AOP编程的支持;声明式事务的支持;方便程序的测试;方便继承各种优秀框架;降低JavaEE的使用难度
2、Spring的耦合及解耦
-
JDBC实例
-
加入MySql坐标依赖,也就是驱动jar包
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
-
实验代码
-
程序的耦合程度大,解决类之间的依赖,但是不能完全消除依赖关系
public class JdbcDemo1 {
public static void main(String[] args) throws SQLException {
//1.注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//2.获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/eesy","root","123456");
//3.获取操作数据库的预处理对象
PreparedStatement pstm = conn.prepareStatement("select * from account");
//4.执行SQL,得到结果集
ResultSet rs = pstm.executeQuery();
//5.遍历结果集
while (rs.next()){
System.out.println(rs.getString("name"));
}
//6.释放资源
rs.close();
pstm.close();
conn.close();
}
}
-
使用反射来创建对象,而避免使用new关键字
-
通过读取配置文件来获取要创建的对象全限定类名
-
问题解决:使用反射实例化IAccountService、IAccountDao对象
-
在不使用框架的情况下,使用Bean工厂模式来生产javaBean对象
-
首先需要一个配置文件:bean.xml 或者properties(键值对)来配置我们的service和dao
-
配置的内容:唯一标识=全限定类名(key = value)
-
通过读取配置文件中的配置信息的内容,反射创建对象;
beanFactory.java
public class BeanFactory {
//定义一个properties对象
private static Properties props;
static {
try {
//实例化对象
props = new Properties();
//获取properties文件的流对象
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
} catch (IOException e) {
throw new ExceptionInInitializerError("读取配置文件失败");
}
}
//根据bean的名称获取bean对象
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;
}
}
配置文件:
accountService = com.cjf.service.impl.AccountServiceImpl
accountDao = com.cjf.dao.Impl.AccountDaoImpl
解耦:
private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao");
-
改造工厂模式
-
工厂创建的对象都是多例的,因为使用了newInstance()
-
改造方法,使用Map来保存创建好的对象,再使用的话还是原来的对象
-
IOC:将实例化对象的控制权由类本身,转交给工厂生产
-
对于Spring框架来说,就是把实例化对象的权利转交给框架
-
注意:控制反转包括 依赖注入 和 依赖查找
-
既然这个功能可以由框架实现,那就省去了我们自己创建bean工厂,这也是使用框架的好处
3、Spring配置IOC
-
首先使用Spring框架必须导入Spring的依赖,maven工程的依赖相当于Eclipse中的jar包
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
导入了四个核心容器
2.接着创建bean.xml,并导入约束,这个约束是基于XML的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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--把对象的创建交给spring来管理-->
<bean id="accountService" class="com.cjf.service.impl.AccountServiceImpl">
</bean>
<bean id="accountDao" class="com.cjf.dao.Impl.AccountDaoImpl">
</bean>
3.表现层代码调用
public class Client {
/*
* /获取Spring的IOC核心容器,并根据id获取对象
*/
public static void main(String[] args) {
//1、获取核心容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2、工具id获取bean对象
IAccountService as = (IAccountService) ac.getBean("accountService");
IAccountDao adao = ac.getBean("accountDao",IAccountDao.class);
System.out.println(as);
System.out.println(adao);
}
}
ApplicationContext三个常用实现类:
-
ClassPathXmlApplicationContext:加载类路径下的配置文件
-
AnnotationConfigApplicationContext:它是用于读取注解创建容器的
-
FileSystemXmLApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)不常用
把对象的创建交给Spring管理:
Spring对Bean的管理细节:
-
创建bean的三种方式
-
bean对象的作用范围
-
bean对象的生命周期
三种方式:
-
默认构造函数,所以最好是不要在service和dao中重写默认构造函数
-
如果不是要直接创建service或者dao对象,而是要创建一个工厂类中的内部类对象,这时使用第二种方法,就是用工厂中的方法来创建
<bean id="" factory-bean="" factory-method=""></bean>
-
直接使用静态方法创建
bean的作用范围
-
singleton:单例的(默认值)
-
prototype:多例的
-
request:作用于web应用的请求范围
-
session:作用于web范围的会话范围
-
global-session:作用于集群环境的会话范围(全局会话范围),不是集群环境时就是session
bean的生命周期
-
单例对象:当容器创建时对象出生,容器销毁对象消亡
-
多例对象:使用对象时创建对象,当对象长时间不用时由java的垃圾回收器回收
依赖关系的维护:就称为依赖注入:通俗的理解就是在一个javabean中可能包含其他的需要反射来解耦的数据,这时需要在配置文件中的<bean>标签中使用<property>来配置要注入的东西,就是依赖注入
能注入的数据,有三类
1、基本类型和String
2、其他bean类型(在配置文件中或者注解配置过的bean)
3、复杂类型/集合类型
注入的方式:有三种
第一种:使用构造函数提供
使用标签:constructor-arg
位置:bean标签的内部
标签中的属性:
name:用于指定给构造函数中指定名称的参数赋值
value:用于提供基本类型和String类型的数据
ref:用于指定其他bean类型的数据,它指的就是在spring 的Ioc核心容器中出现过的bean对象
<bean id="accountService" class="com.cjf.service.impl.AccountServiceImpl">
<constructor-arg name="name" value="test"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="date"></constructor-arg>
</bean>
<bean id="date" class="java.util.Date"></bean>
第二种:使用set方法提供(常用,注意要注入的属性必须含有set方法)
使用的标签:property
出现的位置:bean标签的内部
标签中的属性:
name:用于指定注入是所调用的set方法名称
value:用于提供基本类型和String类型的数据
ref:用于指定其他bean类型的数据,它指的就是在spring的Ioc核心容器中出现过的bean对象
<bean id="accountService2" class="com.cjf.service.impl.AccountServiceImpl2">
<property name="name" value="TEST"></property>
<property name="age" value="20"></property>
<property name="birthday" ref="date"></property>
</bean>
使用set方法注入复杂类型/集合类型
使用的标签:property
出现的位置:bean标签的内部
标签中的属性:
name:用于指定注入是所调用的set方法名称
value:用于提供基本类型和String类型的数据
ref:用于指定其他bean类型的数据,它指的就是在spring的Ioc核心容器中出现过的bean对象
<bean id="accountService3" class="com.cjf.service.impl.AccountServiceImpl3">
<property name="myStrs">
<array>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</array>
</property>
<property name="myList">
<list>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</list>
</property>
<property name="mySet">
<set>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</set>
</property>
<property name="myMap">
<map>
<entry key="key1" value="value1"></entry>
<entry key="key2" value="value2"></entry>
<entry key="key3" value="value3"></entry>
</map>
</property>
<property name="myProps">
<props>
<prop key="prop1">111</prop>
<prop key="prop2">222</prop>
<prop key="prop3">333</prop>
</props>
</property>
</bean>
第三种:使用注解提供