Spring5
1、Spring框架概述
1、Spring 是轻量级的开源的 JavaEE 框架
2、Spring 可以解决企业应用开发的复杂性
3、Spring 有两个核心部分:IOC 和 Aop
(1)IOC:控制反转,把创建对象过程交给 Spring 进行管理
(2)Aop:面向切面,不修改源代码进行功能增强
4、Spring 特点
(1)方便解耦,简化开发
(2)Aop 编程支持
(3)方便程序测试
(4)方便和其他框架进行整合
(5)方便进行事务操作
(6)降低 API 开发难度
入门案例
1.下载Spring5
2.下载
下载地址:https://repo.spring.io/artifactory/release/org/springframework/spring/5.2.16.RELEASE
3.打开idea,创建普通工程
导入相关jar包(从官网下载的工程的lib文件夹获取)
4、创建普通类,在这个类创建普通方法
public class User {
public void say(){
System.out.println("hello spring");
}
}
5、创建 Spring 配置文件,在配置文件配置创建的对象
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置User对象创建-->
<bean id="user" class="com.yxm.User"></bean>
</beans>
6、进行测试代码编写
2、IOC容器
1、什么是IOC?
(1)控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理
(2)使用 IOC 目的:为了耦合度降低
(3)做入门案例就是 IOC 实现
2、IOC底层原理
xml 解析、工厂模式、反射
3、IOC(BeanFactory接口)
1.IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
2.Spring提供IOC容器的两种方式:(两个接口)
(1)BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用
加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
(2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人
员进行使用
加载配置文件时候就会把在配置文件对象进行创建
3、ApplicationContext 接口有实现类
IOC操作Bean管理
什么是Bean管理
Bean管理指的是两个操作
1.Spring创建对象 2.Spring注入属性
Bean管理操作的两种方式
1.xml配置文件方式实现2.基于注解实现
IOC操作Bean管理(基于xml方式)
1.基于xml文件创建对象
(1)在Spring配置文件中,使用Bean标签,标签里面添加对应属性,就可以实现对象创建
(2)bean常用属性
- id属性:唯一标识
- class属性:类全路径
(3)创建对象时候,默认也是执行无参构造方法创建对象
2.基于xml方式注入属性
(1)DI:依赖注入,就是注入属性
第一种注入方式:使用set方法注入
package com.yxm;
public class Book {
private String bname;
//set注入
public void setBname(String bname) {
this.bname = bname;
}
//有参构造注入
public Book(String bname){
this.bname=bname;
}
public static void main(String[] args) {
Book book=new Book("西游记");
System.out.println(book.bname);
}
}
第二种注入方式:在Spring配置文件配置对象创建,属性注入
<!--配置Book对象创建-->
<bean id="book" class="com.yxm.Book">
<!--使用property完成属性注入-->
<property name="bname" value="水浒传"></property>
</bean>
第三种注入方式:通过有参构造注入
1.创建实体类对象
package com.yxm;
public class Order {
private String name;
private String address;
//有参构造
public Order(String name, String address) {
this.name = name;
this.address = address;
}
}
2.在Spring配置文件进行配置
<!--配置Order对象创建有参构造注入-->
<bean id="order" class="com.yxm.Order">
<constructor-arg name="name" value="笔记本"></constructor-arg>
<constructor-arg name="address" value="浙江杭州"></constructor-arg>
</bean>
p名称空间注入
使用p命名空间注入,可以简化基于xml配置
第一步:添加p空间在配置文件中
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
第二步:在bean标签进行属性注入
<!--配置Book对象创建-->
<bean id="book" class="com.yxm.Book" p:bname="红楼梦"></bean>
IOC操作Bean管理(xml注入其他类型属性)
1.字面量
(1)null值
<!--配置Book对象创建-->
<bean id="book" class="com.yxm.Book">
<!--使用property完成属性注入-->
<property name="bname" value="水浒传"></property>
<property name="address">
<null></null>
</property>
</bean>
(2)属性值包含特殊符号
将<>进行转义 < >
<bean id="book" class="com.yxm.Book">
<!--使用property完成属性注入-->
<property name="bname" value="<水浒传>"></property>
<property name="address" value="河南郑州"></property>
</bean>
将特殊符号内容写进CDATA
<bean id="book" class="com.yxm.Book">
<!--使用property完成属性注入-->
<property name="bname">
<value><![CDATA[<水浒传>]]></value>
</property>
<property name="address" value="河南郑州"></property>
</bean>
有点复杂,类似sql存储过程
2.注入属性–外部Bean
创建Service类和dao类
在Spring配置文件配置
<bean id="userService" class="com.yxm.service.UserService">
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<bean id="userDaoImpl" class="com.yxm.dao.UserDaoImpl"></bean>
3.注入属性–内部Bean
一对多关系:部门和员工
部门类
package com.yxm;
//部门类
public class Dept {
private String dname;
public void setDname(String dname) {
this.dname = dname;
}
}
员工类
package com.yxm;
//员工类
public class Emp {
private String ename;
private String gender;
private Dept dept;
public void setEname(String ename) {
this.ename = ename;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setDept(Dept dept) {
this.dept = dept;
}
}
在Spring文件进行配置
<bean id="emp" class="com.yxm.Emp">
<property name="ename" value="呆瓜"></property>
<property name="gender" value="男"></property>
<property name="dept">
<bean id="dept" class="com.yxm.Dept">
<property name="dname" value="开发部"></property>
</bean>
</property>
</bean>
级联赋值
<bean id="emp" class="com.yxm.Emp">
<property name="ename" value="呆瓜"></property>
<property name="gender" value="男"></property>
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.yxm.Dept">
<property name="dname" value="开发部"></property>
</bean>
IOC操作Bean管理(xml注入集合属性)
注入数组,List集合,Map集合类型属性
创建实体类
public class Stu {
private String[] course;
private List<String> list;
private Map<String,String> map;
private Set<String> set;
public void setCourse(String[] course) {
this.course = course;
}
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;
}
}
在Spring配置文件配置
<bean id="stu" class="com.yxm.Stu">
<!--数组-->
<property name="course">
<array>
<value>java</value>
<value>c++</value>
<value>js</value>
</array>
</property>
<!--list集合-->
<property name="list">
<list>
<value>张三</value>
<value>李四</value>
<value>王五</value>
</list>
</property>
<!--set集合-->
<property name="set">
<set>
<value>吃饭</value>
<value>睡觉</value>
<value>打豆豆</value>
</set>
</property>
<!--map集合-->
<property name="map">
<map>
<entry key="1" value="java"></entry>
<entry key="2" value="c"></entry>
</map>
</property>
</bean>
IOC操作Bean管理(xml自动装配)
什么是自动装配?
根据指定装配规则(属性名称或属性类型),Spring自动将匹配的属性值进行注入
实现自动装配
bean标签属性autowire,配置自动装配
autowire属性常用两个值:
byName:根据属性名称注入,注入值bean的id和类属性名称一样
byType:根据属性类型注入
创建Emp类和Dept类
public class Emp {
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Emp{" +
"dept=" + dept +
'}';
}
public void test(){
System.out.println(dept);
}
}
public class Dept {
@Override
public String toString() {
return "Dept{}";
}
}
创建配置文件
<bean id="emp" class="com.yxm.Emp" autowire="byName"></bean>
<bean id="dept" class="com.yxm.Dept" ></bean>
测试:
@Test
public void testautpwire(){
ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");
Emp emp=context.getBean("emp",Emp.class);
System.out.println(emp);
}
IOC操作Bean管理(外部属性文件)
1.不通过外部配置文件直接配置数据库信息
配置德鲁伊数据库连接池
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/sys"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
2.引入外部配置文件配置数据库信息
1.创建配置文件jdbc.properties
prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/sys
prop.username=root
prop.password=123456
2.把外部文件引入Spring配置文件
引入context名称空间
<?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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
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/beans/spring-context.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${prop.driverClass}"></property>
<property name="url" value="${prop.url}"></property>
<property name="username" value="${prop.username}"></property>
<property name="password" value="${prop.password}"></property>
</bean>
IOC操作Bean管理(基于注解方式)
1.什么是注解?
(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值…)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解目的:简化 xml 配置
2、Spring 针对 Bean 管理中创建对象提供注解
(1)@Component(通用注解)
(2)@Service(Service层)
(3)@Controller(Controller层)
(4)@Repository(Dao层)
- 上面四个注解功能是一样的,都可以用来创建 bean 实例
3、基于注解方式实现对象创建
1.引入依赖AOP
2.开启组件扫描
<context:component-scan base-package="com.yxm.test"/>
3.创建类,在类上添加注解
@Component(value = "userService")
public class UserService {
public void add(){
System.out.println("service add");
}
}
测试
4.基于注解方式实现属性注入
(1)@AutoWired:根据属性类型进行自动装配
@Service
public class UserService {
@Autowired
private UserDao userDao;
public void add(){
System.out.println("service add");
userDao.add();
}
}
(2) @Qualifer:根据属性名称进行注入
这个@Qualifier 注解的使用,和上面@Autowired 一起使用
@Autowired
@Qualifier(value = "userDaoImpl1")
private UserDao userDao;
public void add() {
System.out.println("service add");
userDao.add();
}
(3) @Resource:可以根据类型或者名称注入
@Autowired
@Resource(name = "userDaoImpl1")
private UserDao userDao;
public void add() {
System.out.println("service add");
userDao.add();
}
(4) @Value:注入普通属性
@Value(value = "abc")
private String name;
3、 AOP
什么是AOP?
AOP面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP相关术语
1.连接点:类里面哪些方法可以被增强,这些方法称为连接点
2.切入点:实际被增强的方法,成为切入点
3.通知(增强):实际增强的逻辑部分称为通知(增强)
通知分为:前置通知、后置通知、环绕通知、异常通知、最终通知
4.切面:是动作把通知应用到切入点过程
AOP操作
1.Spring框架一般基于AspectJ实现AOP操作
基于xml配置方式
基于注解(使用)
2.在项目工程引入AOP相关依赖
3.切入点表达式
(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
(2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )
举例 1:对 com.yxm.dao.BookDao 类里面的 add 进行增强
execution(* com.yxm.dao.BookDao.add(…))
举例 2:对 com.yxm.dao.BookDao 类里面的所有的方法进行增强
execution(* com.yxm.dao.BookDao.* (…))
举例 3:对 com.yxm.dao 包里面所有类,类里面所有方法进行增强
execution(* com.yxm,.dao.. (…))
AOP 操作(AspectJ 注解)
1.创建类,在类里面定义方法
public class User {
public void add(){
System.out.println("add....");
}
}
2.创建增强类(编写增强逻辑)
在增强类里面,创建方法,让不同方法代表不同通知类型
public class UserProxy {
//前置通知
public void before(){
System.out.println("before.....");
}
}
3.在配置文件进行通知配置
(1)在Spring配置文件中开启注解扫描
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.yxm.test.aop"/>
</beans>
(2)使用注解创建User和UserProxy对象
(3)在增强类上面添加注解 @Aspect
(4)在 spring 配置文件中开启生成代理对象
<!--开启aspectj生成代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
4.配置不同类型的通知
(1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
@Component
@Aspect
public class UserProxy {
//前置通知
@Before(value = "execution(* com.yxm.test.aop.User.add(..))")
public void before(){
System.out.println("before.....");
}
//后置通知(返回通知)
@AfterReturning(value = "execution(* com.yxm.test.aop.User.add(..))")
public void afterReturning(){
System.out.println("afterReturning.....");
}
//最终通知
@After(value = "execution(* com.yxm.test.aop.User.add(..))")
public void after(){
System.out.println("after.....");
}
//异常通知
@AfterThrowing(value = "execution(* com.yxm.test.aop.User.add(..))")
public void afterThrowing(){
System.out.println("afterThrowing.....");
}
//环绕通知
@Around(value = "execution(* com.yxm.test.aop.User.add(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕之前.....");
proceedingJoinPoint.proceed();
System.out.println("环绕之后.....");
}
}
测试:
5.相同切入点抽取
//切入点抽取
@Pointcut(value = "execution(* com.yxm.test.aop.User.add(..))")
public void pointcut(){
}
//前置通知
@Before(value = "pointcut()")
public void before(){
System.out.println("before.....");
}
6.有多个增强类同一个方法进行增强,设置增强类优先级
@Order注解实现,数字类型值越小优先级越高