框架简介
- 框架: 具有约束性的去支撑我们实现各种功能的半成品项目.
- 简单说就是使用别人搭好的舞台,你来做表演.
- 即框架封装了各种技术, 但缺少业务逻辑.
- 项目 = 框架 + 业务逻辑.
- MVC
- M: 模型层; V: 视图; C: 控制器;
- 客户端发送一个请求
- 控制层进行处理
- 由模型层装载并传输数据, 并在视图层进行展示.
- 框架的历史
- MVC框架
- struct1(封装了Servlet), struct2(封装了过滤器).
- springMVC(封装了Servlet)
- 持久层框架
- hibernate(自动化持久层框架)
- mybatis(半自动化持久层框架)
- 整合型框架
- spring
- MVC框架
Spring概述
- 简介
- Spring为简化企业级开发而生.
- 使用Spring,JavaBean就可以实现很多以前要靠EJB才能实现的功能.
- 同样的功能,在EJB中要通过繁琐的配置和复杂的代码才能够实现,而在Spring中却非常的优雅和简洁.
- Spring是一个IOC(DI)和AOP容器框架.
- Spring的优良特性
- 非侵入性: 该框架对原来的技术不造成影响
- 依赖注入: DI, 是反转控制(IOC)最经典的实现
- 面向切面编程: AOP, 是对OOP的补充.
- 容器: Spring是一个容器, 因为包含并管理应用对象的生命周期.
- 组件化: Spring实现了使用简单的组件配置组合成一个复杂的应用.
- 可用XML或注解组合这些对象.
- 一站式: IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的 第三方类库.
- 搭建Spring环境
- 新建一个maven项目
- 导入依赖
<properties> <spring.version>5.0.8.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
- 在Resources下创建一个Spring Config
- applicationContext.xml
- 案例
- 目标: 使用Spring创建对象, 为属性赋值
- 创建Person类
public class Person { private Integer id; private String name; //... }
- 创建Spring配置文件: applicationContext.xml
- 使用bean元素定义一个由IOC容器创建的对象.
- class属性指定用于创建bean的全类名
- id属性是该对象的唯一标识, 不能重复. 在通过类型获取bean中可以不设置.
- scope为作用域, singleton为单例, prototype为原型.
- property子元素为bean的属性赋值
- name: 属性名, value:属性值
<bean id="person" class="spring.bean.Person"> <property name="id" value="111"></property> <property name="name" value="zhangsan"></property> </bean>
- 测试
- 通过Spring的IOC容器创建Person类实例: TestBySpring.java
- 初始化容器
- ClassPathXmlApplicationContext("配置文件路径");
- getBean()获取对象
- getBean(String id): 这样获取的是Object对象.
- getBean(类名.class): 使用此方法获取对象时, 要求spring管理的此类型的对象只能有一个.
- getBean(id, 类名.class): 最好使用这个方法.
public class TestBySpring { public static void main(String[] args) { //初始化容器 ClassPathXmlApplicationContext cac = new ClassPathXmlApplicationContext("applicationContext.xml"); //通过getBean()获取对象 Person person = cac.getBean("person", Person.class); System.out.println(person); cac.close(); } }
- Spring是如何帮我们创建对象的?
- 我们把对象以bean标签的形式写入spring的配置文件中.
- 初始化容器时会加载配置文件并读取.
- 用反射forName("全类名")获取class对象, 再通过newInstance()方法创建对象.
Spring配置介绍
- IOC和DI
- IOC: 反转控制
- 把原来由程序员管理对象的权利反转给程序本身, 让程序自己管理.
- 反转控制思想
- 反转了资源的获取方向——改由容器主动的将资源推送给需要的组件, 开发人员不需要知道容器是如何创建资源对象的,只需要提供接收资源 的方式即可,极大的降低了学习成本,提高了开发的效率。这种行为也 称为查找的被动形式.
- 举例: 原来自己买菜做饭, 现在点外卖(不用知道操作细节)
- DI: 依赖注入
- DI是IOC的另一种表述方式, 即组件以一些预先定义好的方式(如setter) 接受来自于容器的资源注入, 相对于IOC而言, 这样更直接.
- 依赖谁就注入谁(为谁赋值)
- 总结: IOC是一种反转控制思想, 而DI是它的具体实现.
- IOC容器在Spring中的实现
- 前提: spring中的IOC思想需基于IOC容器完成, 而IOC容器在最底层是个对象工厂.
- 在通过IOC读取Bean实例前, 需先将IOC容器本身实例化.
- spring提供了IOC容器的两种实现方式
- BeanFactory: 基本实现, 是spring内部的基础设施, 面向spring本身, 不提供给开发人员使用.
- ApplicationContext: BeanFactory的子接口, 提供了更多高级特性。面向Spring的使用者.
- 几乎所有场合都使用ApplicationContext而不是底层的BeanFactory.
- Application的主要实现类
- 两个主要实现类
- ClassPathXmlApplicationContext: 对应类路径下的xml格式的配置文件.(写相对路径)
- FileSystemXmlApplicationContext: 加载磁盘路径下的配置文件.
- Application的子接口
- ConfigurableApplicationContext
- 包含一些扩展方法: refresh()和close()让ApplicationContext具有启动, 关闭和刷新上下文的能力.
- WebApplicationContext
- 专门为Web应用而准备的, 它允许从相对于web根目录的路径中完成初始化工作.
- ConfigurableApplicationContext
- 给bean的属性赋值
- 依赖注入方式
- set注入: 用property标签
<bean id="person" class="Person" scope="singleton"> <property name="id" value="222"></property> <property name="name" value="李四"></property> </bean>
- 这里是利用setXxx()进行赋值的.
- 构造方法注入: 用constructor-arg标签
- constructor-arg中的参数: index(索引), name(参数名), ref(引用), type(类型), value(值)
- 会自动匹配类中相应的构造方法.
<bean id="person3" class="top.binwenhome.spring.bean.Person"> <constructor-arg value="333"></constructor-arg> <constructor-arg value="wangwu"></constructor-arg> </bean>
- 若有重载的构造方法, 用name注明参数.
<bean id="person4" class="top.binwenhome.spring.bean.Person"> <constructor-arg name="name" value="zhaoliu"></constructor-arg> </bean>
- set注入: 用property标签
- p名称空间
- 引入P名称空间后, 可在bean标签中通过p:属性进行赋值
<bean id="person5" class="top.binwenhome.spring.bean.Person" p:id="444" p:name="xiaoming"> </bean> IDEA中的名称空间是可以自动导入的.
- 引入P名称空间后, 可在bean标签中通过p:属性进行赋值
- 为属性赋值时可以使用的值
- 字面量
- 能把值写成字符串方式的就叫字面量
- 如: 所有基本类型及其包装类, String
- 可以直接赋null值.
- value只能填写字面量, 若要填其他内容, 需用ref标签
- 引用: 用于引用当前spring管理范围内bean的id
<bean id="teacher1" class="bean.Teacher"> <property name="tid" value="1"></property> <property name="tname" value="xiaoming"></property> </bean> <bean id="student1" class="bean.Student"> <property name="id" value="11"></property> <property name="name" value="xiaohong"></property> <property name="age" value="18"></property> <property name="sex" value="female"></property> <property name="teacher" ref="teacher1"></property> </bean>
- 引用: 用于引用当前spring管理范围内bean的id
- 给bean的级联属性
<bean id="teacher1" class="bean.Teacher"> <property name="tid" value="1"></property> <property name="tname" value="xiaoming"></property> </bean> <bean id="student1" class="bean.Student"> <property name="id" value="11"></property> <property name="name" value="xiaohong"></property> <property name="age" value="18"></property> <property name="sex" value="female"></property> <property name="teacher" ref="teacher1"></property> <property name="teacher.tid" value="2"></property> </bean> 这样, tid就从1变成了2
- 内部bean
- 当bean实例仅仅给一个特定的属性使用时, 可以将其声明为内部bean.
- 内部bean声明直接包含在<property>或<constructor-arg>元素里, 不 需要设置任何id或name属性.
<bean id="student1" class="bean.Student"> <property name="id" value="11"></property> <property name="name" value="xiaohong"></property> <property name="age" value="18"></property> <property name="sex" value="female"></property> <property name="teacher"> <bean class="bean.Teacher" p:tid="3" p:tname="haha" ></bean> </property> </bean>
集合属性
- 在spring中可以通过一组内置的xml标签来配置集合属性, 如<list>, <map>
- 数组, list, set
- 配置数组内元素属性时, 需要指定<array>标签.
- 通过<value>指定简单的常量值.
- 通过<ref/>指定对其他Bean的引用: 使用<ref bean="id" />
- 通过<bean>指定内置bean.
- 通过<null/>指定空元素, 甚至可以内嵌其他集合.
- 配置List类型的属性: <list>, 和<array>类似
- 配置set类型属性: <set>, 和<array>类似
<bean id="teacher" class="bean.Teacher"> <property name="tid" value="102"></property> <property name="tname" value="xiaoming"></property> <property name="grades"> <array> <value>一年级</value> <value>二年级</value> </array> </property> <property name="persons"> <list> <ref bean="person" /> <ref bean="person2" /> <ref bean="person3" /> </list> </property> </bean>
- Map
- <map>标签里可以使用多个<entry>作为子标签, 每个条目包含一个键和值.
- 必须在<key>标签里定义键.
- 因为键和值的类型无限制, 故可以自由地指定<value>, <ref/>, <bean>或 <null/>
<bean id="teacher" class="bean.Teacher"> <property name="tid" value="102"></property> <property name="tname" value="xiaoming"></property> <property name="map"> <map> <entry> <key><value>1</value></key> <ref bean="person2"></ref> </entry> <entry> <key><value>2</value></key> <ref bean="person3"></ref> </entry> </map> </property> </bean>
- 集合类型的bean
- 若只能将集合对象配置在某个bean内部, 则该集合对象的配置不能重用, 我们将 集合bean的配置拿到外面, 供其他bean引用.
- 需要用到util名称空间
<bean id="teacher" class="bean.Teacher"> <property name="tid" value="102"></property> <property name="tname" value="xiaoming"></property> <property name="persons" ref="list"></property> <property name="grades" ref="string"></property> </bean> <util:list id="string"> <value>一年级</value> <value>二年级</value> <value>三年级</value> </util:list> <util:list id="list"> <ref bean="person" /> <ref bean="person2" /> <ref bean="person3" /> </util:list>
FactoryBean
-
spring中有两种类型的bean, 一种是普通bean, 另一种是工厂bean, 即 FactoryBean.
- 工厂Bean
- 工厂模式就是把创建对象的过程交给工厂, 工厂创建好后交给我们.
- FactoryBean是个接口, 实现了该接口的类就是工厂Bean.
- 要实现三个抽象方法
- getObject(): 获取对象
- getObjectType(): 获取对象类型
- isSingleton(): 是否为单例
- 要实现三个抽象方法
- 举例
- Car
public class Car { private String brand; private Double price; }
- MyFactory
public class MyFactory implements FactoryBean<Car> { @Override public Car getObject() throws Exception { Car car = new Car("baoma", 3000000D); return car; } @Override public Class<?> getObjectType() { return Car.class; } @Override public boolean isSingleton() { return false; } }
- 配置文件
<!-- 虽然这里写的是工厂的全类名, 但实际返回的是工厂创建的对象: getObject()返回的对象 --> <bean id="factory" class="factory.MyFactory"></bean>
- 测试
Object bean = cac.getBean("factory"); System.out.println(bean);
- Car