Spring学习
Spring概述
Spring是另一个主流的java Web开发框架,该框架是一个轻量级的开源的应用框架,具有很高的凝聚力和吸引力、可以解决企业应用开发的复杂性。Spring框架因其强大的功能以及卓越的性能而受到众多开发人员的喜爱。
Spring 是分层的 Java SE/EE full-stack 轻量级开源框架,以 IoC(Inverse of Control,控制反转):把创建对象过程交给Spring进行管理和 AOP(Aspect Oriented Programming,面向切面编程)为内核,使用基本的 JavaBean 完成以前只可能由 EJB 完成的工作,取代了 EJB 臃肿和低效的开发模式。
在实际开发中,通常服务器端采用三层体系架构,分别为表现层(web)、业务逻辑层(service)、持久层(dao)。
Spring 具有简单、可测试和松耦合等特点,不仅可以用于服务器端的开发,也可以应用于任何 Java 应用的开发中。Spring 框架的主要优点具体如下。
1)方便解耦,简化开发
Spring 就是一个大工厂,可以将所有对象的创建和依赖关系的维护交给 Spring 管理。
2)方便集成各种优秀框架
Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如 Struts2、Hibernate、MyBatis 等)的直接支持。
3)降低 Java EE API 的使用难度
Spring 对 Java EE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了封装,使这些 API 应用的难度大大降低。
4)方便程序的测试
Spring 支持 JUnit4,可以通过注解方便地测试 Spring 程序。
5)AOP 编程的支持
Spring 提供面向切面编程,可以方便地实现对程序进行权限拦截和运行监控等功能。
6)声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无须手动编程。
-
Spring 框架采用分层架构,根据不同的功能被划分成了多个模块,这些模块大体可分为 Data Access/Integration、Web、AOP、Aspects、Messaging、Instrumentation、Core Container 和 Test,如图 1 所示。
图 1 中包含了 Spring 框架的所有模块,这些模块可以满足一切企业级应用开发的需求,在开发过程中可以根据需求有选择性地使用所需要的模块。下面分别对这些模块的作用进行简单介绍。
1. Data Access/Integration(数据访问/集成)
数据访问/集成层包括 JDBC、ORM、OXM、JMS 和 Transactions 模块,具体介绍如下。
-
JDBC 模块:提供了一个 JDBC 的抽象层,大幅度减少了在开发过程中对数据库操作的编码。
-
ORM 模块:对流行的对象关系映射 API,包括 JPA、JDO、Hibernate 和 iBatis 提供了的集成层。
-
OXM 模块:提供了一个支持对象/XML 映射的抽象层实现,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。
-
JMS 模块:指 Java 消息服务,包含的功能为生产和消费的信息。
-
Transactions 事务模块:支持编程和声明式事务管理实现特殊接口类,并为所有的 POJO。
2. Web 模块
Spring 的 Web 层包括 Web、Servlet、Struts 和 Portlet 组件,具体介绍如下。
-
Web 模块:提供了基本的 Web 开发集成特性,例如多文件上传功能、使用的 Servlet 监听器的 IoC 容器初始化以及 Web 应用上下文。
-
Servlet模块:包括 Spring 模型—视图—控制器(MVC)实现 Web 应用程序。
-
Struts 模块:包含支持类内的 Spring 应用程序,集成了经典的 Struts Web 层。
-
Portlet 模块:提供了在 Portlet 环境中使用 MV C实现,类似 Web-Servlet 模块的功能。
3. Core Container(核心容器)
Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上下文模块和 Expression Language 表达式语言模块组成,具体介绍如下。
-
Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称为 Bean。
-
Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
-
Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
-
Expression Language 模块:是运行时查询和操作对象图的强大的表达式语言。
4. 其他模块
Spring的其他模块还有 AOP、Aspects、Instrumentation 以及 Test 模块,具体介绍如下。
-
AOP 模块:提供了面向切面编程实现,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。
-
Aspects 模块:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架。
-
Instrumentation 模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
-
Test 模块:支持 Spring 组件,使用 JUnit 或 TestNG 框架的测试。
Spring入门案例
-
下载Spring框架
-
进入spring逛网 https://spring.io/ ------> 选中 spring-framework
-
选择github
-
进入页面后 向下拉 找到下图位置
点进去 找到下图位置
出现的 https://repo.spring.io就是下载地址
-
加载jar步骤
-
创建一个User实体类
public class User {
public void add(){
System.out.println("add....");
}
}
-
配置spring文件
-
创建一个测试类
public class SpringTest {
-
什么是控制反转?
-
是面向对象编程的一种设计原则,可以用来减低计算机代码之间的耦合性,其中最常见的方式叫做依赖注入(DI)
-
把对象创建和对象之间的调用过程,交给Spring进行管理
-
-
IOC底层原理
-
xml解析,工厂那个模式、反射
-
IOC重要的接口
-
IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
-
spring提供IOC容器实现两种方式(两个接口)
-
BeanFactory :IOC容器基本实现(Spring自带接口,一般开发不使用),* 加载配置文件时候不会创建对象,在获取对象(使用对象)才会创建对象
-
ApplicationContext:BeanFactory 的子接口,提供更多,更强大的功能(一般由开发人员进行使用),*加载配置文件时候会把配置文件对象进行配置
-
-
ApplicationContext接口的实现类
-
FileSystemXmlApplicationContext:盘符路径(全路径)
-
ClassPathXmlApplicationContext:目录路径
-
-
-
-
IOC:Bean管理xml
-
什么是Bean管理(2个操作)
-
Spring创建对象
-
Spring注入属性
-
-
Bean管理的两种方式
-
基于xml配置文件实现
-
基于xml方式创建对象
-
在Spring配置文件中,使用bean标签,标签里添加相应的属性,就可以实现创建对象
-
在bean标签有很多属性
-
id属性:表示给对象起一个唯一标识
-
class属性:创建对象所在类的全路径
-
name属性:和id属性类似,用的不多,区别在于id属性中不能加入特殊属性,name属性可以
-
创建对象时候,默认执行无参构造方法完成对象创建
-
-
<bean id="user" class="com.company.User"></bean>
-
-
基于xml方式注入属性
-
DI:依赖注入,就是注入属性
<!-- 创建User对象-->
<bean id="user" class="com.company.User">
<!-- set方法注入属性 注意 实体类中要对属性进行set***()否则报错-->
<property name="bName" value="张三"></property>
</bean>name属性:对象的属性字段
value属性:注入对象属性
有参构造方法注入属性
public class Book {
private String bName;
private String author;
public Book(String bName, String author) {
this.bName = bName;
this.author = author;
}
public Book() {
}
}<bean id="book" class="com.company.Book">
<!-- 有参构造方法注入属性-->
<constructor-arg name="author" value="张三"></constructor-arg>
<constructor-arg name="bName" value="有参构造注入"></constructor-arg>
<!-- <constructor-arg index="0" value="oo"></constructor-arg>-->
</bean>index属性:实体类中属性的下标
-
-
-
IOC操作Bean管理(xml注入其他类型属性)
-
字面量
-
null值
<!-- 创建User对象-->
<bean id="user" class="com.company.User">
<!-- set方法注入属性-->
<property name="bName" value="张三"></property>
<!--null-->
<property name="age">
<null/>
</property>
</bean>
-
属性值包含特殊符号
<!-- 创建User对象-->
<bean id="user" class="com.company.User">
<!-- 属性值中含有特殊符号-->
<property name="bName" >
<value>
<![CDATA[《南京》]]>
</value>
</property>
</bean> -
注入外部Bean
public class User {
private int age;
private String bName;
private Book book;
public void add(){
System.out.println("add....");
}
public void setbName(String bName) {
this.bName = bName;
}
public String getbName() {
return bName;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}<!-- 创建User对象-->
<bean id="user" class="com.company.User">
<!-- 属性值中含有特殊符号-->
<property name="bName" >
<value>
<![CDATA[《南京》]]>
</value>
</property>
<property name="book" ref="book"></property>
</bean>
-
-
ref属性:引用外部对象
-
-
-
-
一对多关系:部门dept和员工Emp
一个部门有多个员工,一个员工属于一个部门
-
在实体类之间表示一对多关系
部门类
public class Dept {
private String name;
public void setName(String name) {
this.name = name;
}
员工类
public class Emp {
private String name;
private int age;
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
配置文件
<bean name="emp" class="com.company.Bean.Emp">
<property name="name" value="张三"/>
<property name="age" value="45"/>
<property name="dept">
<bean name="dept" class="com.company.Bean.Dept">
<property name="name" value="开发部" />
</bean>
</property>
</bean>
测试
Emp{name='张三', age=45, dept=Dept{name='开发部'}}
-
-
注入属性---级联赋值(注意要生成getDept()方法)
<bean name="dept" class="com.company.Bean.Dept"></bean>
<bean name="emp" class="com.company.Bean.Emp">
<property name="dname" value="张三"/>
<property name="age" value="45"/>
<property name="dept" ref="dept" />
<property name="dept.name" value="开发部" />
</bean>
数组类型注入属性
-
创建实体类 并创建set方法
public class Student {
private String[] strings;
private List<String> list;
private Map<String,String> map;
private Set<String> set;
private List<User> userList;
public void setUserList(List<User> userList) {
this.userList = userList;
}
public void setStrings(String[] strings) {
this.strings = strings;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setSet(Set<String> set) {
this.set = set;
}
}
-
配置文件
<bean name="stu" class="com.company.collect.Student">
<property name="strings" >
<array>
<value>String1</value>
<value>String2</value>
</array>
</property>
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
<property name="map">
<map>
<entry key="JAVA" value="java"></entry>
</map>
</property>
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
</bean>
-
结果
Student{strings=[String1, String2], list=[list1, list2], map={JAVA=java}, set=[set1, set2]}
-
在集合里面设置对象类型值
<property name="userList">
<list>
<ref bean="user" ></ref>
</list>
</property>
<!-- 创建User对象-->
<bean id="user" class="com.company.User">
<!-- 属性值中含有特殊符号-->
<property name="bName" >
<value>
<![CDATA[《南京》]]>
</value>
</property>
</bean>
-
百度查询 把集合值提取出来当成一个公共值
-
工厂Bean (返回的类型可以和定义的类型不一致)
工厂bean
package com.company.factory;
import com.company.Bean.Emp;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Factory implements FactoryBean<Person> {
返回bean
package com.company.factory;
public class Person {
public String name;
-
bean的单实例还是多实例的属性
scope="prototype" 多实例 scope属性
scope="singleton" 单实例
-
bean的初始方法和销毁方法 (百度查询 bean的生命周期)
init-method:初始方法
destroy-method:销毁方法(ClassPathXmlApplicationContext)context.close(); 手动销毁bean
-
-
-
-
-
-
-
-
什么是注解
-
注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值)
-
使用注解,注解作用在类上面,方法上面,属性上面
-
使用注解的目的:简化xml配置
-
-
Spring针对Bean管理中创建对象提供注解 基于注解创建对象
-
@Component
-
@Service
-
@Controller
-
Repository
-
上面四个注解功能是一样的,都可以用来创建Bean实例
-
-
基于注解实现的步骤
-
加入依赖
-
spring-aop-***.jar
-
-
创建扫描器
-
-
-
创建实体类 并加上注解
package com.pack.it;
import org.springframework.stereotype.Repository;
-
测试类(上面四个注解都是一样的)
-
-
基于注解 的扫描 细节
<!--
use-default-filters="false :表示不全扫描所有的类
context:include-filter :只扫描包里带有Controller的注解
context:exclude-filter:扫描除了包里带有Service的注解
-->
<context:component-scan base-package="com.pack" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan> -
基于注解实现属性注入
-
-
@Autowired:根据你的属性类型进行自动装配
-
第一步:把service和dao对象创建,在service和dao类上添加创建对象注解
-
第二步:把service注入dao对象,在service类添加dao类型属性,在属性上使用注解
-
-
public interface UserDao {
public void say();
} -
-
-
-
Qualifier:根据属性名称注入
-
判断使用具体的哪一个类注入 (根据定义的名称)
-
-
-
-
@Resource:上面两种的功能集成
-
-
@Value:注入普通类型属性 主要是不是对象的普通类型
-
-
完全注解开发
-
-