Spring
一 Spring简述:
1.1 Spring: 相较EJB而言,是一个轻量级(好用/难用) DI/IOC 的AOP 框架;
框架: 是一个半成品工具,导入公共代码封装后的jar包;
IOC(Inverse Of Control) : 控制反转(创建对象的过程)------>把创建对象的权力交个Spring
Spring核心配置文件(applicationContext.xml): 启动Spring 就会创建该配置文件中类的对象,不用手动创建;
Spring创建对象的流程:
*通过读取xml配置文件,获得bean标签或者扫描包的标签;
*通过bean标签获取class属性值,或者递归扫描到的加注解类的完全限定名;
*通过反射创建其对象: Class对象.fromName();创建字节码对象
*通过反射调用无参构造 Class对象.newInstance() 创建对象
* 以bean标签的id属性或类名称作为键,以创建出来的对象为值,形成键值对保存到Spring容器 中【Map集合】
DI(Dependency Injection): 依赖注入(初始化对象属性)--------->把Spring 容器创建的对象动态注入到字段的过程;
AOP: 面向切面编程------>解耦代码,维护度高(高内聚,低耦合)
*在不改变原码的情况下,在其方法前后插入业务逻辑(灵活,具有良好的扩展性)
ps:
IOC---为什么要控制反转
*传统--new对象-->耦合度较高--Interface List<T> 泛型降低new对象的耦
合度--任然存在耦合度->工厂模式完全解决实例化对象耦合度--一类创一
工厂---><!--最终:XML配置+反射创建对象+工厂模式(Spring底层原理)-->
1.2 模块化
模块化目的: 高内聚,低耦合 职责分离;
模块化特征: 相互独立,可替换,通用 ;
二 Spring创建对象的四种方式
2.1准备工作
2.1.1 创建项目+导包
2.1.2 引入约束
相对路径:spring-framework-4.1.2.RELEASE\docs\spring-framework-reference\html\index.xml_打开搜索beans_复制约束
<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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 将MyBean对象交个spring管理 -->
<bean id="mybean" class="com.xgl.bean.MyBean"></bean>
<bean id="mybean2" class="com.xgl.bean.MyBean"></bean>
</beans>
2.3 五种方式
2.3.1 手动创建
@Test
public void test() {
MyBean myBean = new MyBean();
System.out.println(myBean); //手动创建
}
2.3.2 通过bean id创建
@Test
public void testSpring_1() {
//创建Resource 对象
Resource resource = new ClassPathResource("applicationContext.xml");
//依据Resource 对象创建BeanFactory对象
BeanFactory beanFactory = new XmlBeanFactory(resource);
//创建Bean对象
MyBean bean = (MyBean)beanFactory.getBean("mybean");
System.out.println(bean);
}
2.3.3 通过类型创建
@Test
public void testSpring_2() {
//创建BeanFactory 对象
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
//创建Bean对象
MyBean bean = beanFactory.getBean(MyBean.class);
System.out.println(bean);
}
2.3.4 通过bean id + 类型创建
@Test
public void testSpring_3() {
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
MyBean bean = beanFactory.getBean("mybean", MyBean.class);
System.out.println(bean);
}
2.3.5 ApplicationContext 接口创建(推荐)
@Test
public void testSpring_4() {
//创建ApplicationContext 对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取bean对象
MyBean bean = applicationContext.getBean("mybean2", MyBean.class);
System.out.println(bean);
}
2.4 BeanFactory 与 ApplicationContext 区别
相同点:
_1 都是接口,其中ApplicationContext是BeanFactory的子接口;
不同点:
_1 ApplicationContext功能更强大,比如可以直接访问资源,国际化....
_2 ApplicationContext:迫切加载,启动Spring容器时创建applicationContext.xml中类的对象;(启动慢,运行快);
_3 BeanFactory: 属于懒加载,只有使用时才会创建;(启动快,运行慢)
ps: 建议使用ApplicationContext,对象创建完毕后再使用,更高效;
三 Spring单元测试
传统的Spring测试: 每一次测试都要加载Spring容器
Spring框架测试: 只需启动一侧Spring容器
//使用Spring 测试
@RunWith(SpringJUnit4ClassRunner.class)
//加载配置文件,创建对象
//@ContextConfiguration("classpath:applicationContext.xml")
//默认在当前包下找 当前类名-Context.xml 的文件
@ContextConfiguration
public class SpringJunit4Test {
/**
* @Autowired : 自动注入
* 先根据类型注入,失败后再根据name (bean id)注入
*/
@Autowired
private MyBean mybean;
@Test
public void test() {
System.out.println(mybean);
}
}
四 作用域&生命周期&属性注入
4.1 作用域
<!-- ioc: 将类的对象交个Spring管理 -->
<!-- Spring Bean 作用域:
singleton: 只会创建一个实例
prototype: 当前配置对bean请求一次创建一个实例
request: 每一次的http的请求,都会创建一个全新的bean实例
session: 每一次会话一实例
global session: 非分布式 相当于session
-->
<bean id="scop" class="com.xgl.scop.SpringScop" scope="prototype"></bean>
4.2 生命周期
*Bean对象(任何对象)----->委托给Spring管理[目的:解耦 ]: 创建–init()—>按需调用Bean对象存在的方法—>销毁
<bean id="life" class="com.xgl._04lifeMethod.LifeMethod"init-method="init"destroy method="destory"/>
4.3 属性注入
value 与 ref 值区别:
_1 value的值: 一般8中基本数据类型及其包装类,String.....
_2 ref的值: 只能是对象;
<bean id="di" class="com.xgl._05propertoyDI.PropertorDI">
<property name="name" value="测试"></property>
<property name="animal" ref="animal"></property>
</bean>
<bean id="animal" class="com.xgl._05propertoyDI.Animal" />
五 三层架构
5.1 图解
5.2 三层架构搭建案例简述
_1 搭建三层架构: daomain--->dao___daoimpl---->service___serviceimpl---->controller
_2 创建相关的接口与类...
_3 将每一层的类交给Spring 管理
_4 Spring 单元测试: daoimpl 是否在控制台打印信息
ps: applicationContext.xml 简化版
<bean id="dao" class="ADaoimpl"></bean>
<bean id="service" class="BServiceimpl">
<property name="aDaoImpl" ref="dao"></property>
</bean>
<bean id="controller" class="CController">
<property name="bServiceImpl" ref="service"></property>
</bean>
六 连接池
6.1 新建db.properties文件
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123456
6.2 引入约束
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
6.3 连接池
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
</bean>
6.4 测试连接
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
private DataSource dataSource;
@Test
public void test() throws Exception {
System.out.println(dataSource); //存在即成功
}
}