目录
简介
Spring是于2003年兴起的一个轻量级的,IOC和AOP的Java开发框架,它是为了简化企业应用级开发而生的。
轻量级的:Spring框架使用的jar都较小,运行占用的资源少,效率高。
IOC:Inversion of Control 控制反转,将项目中有以前自己创建的对象,转而交给Spring框架统一管理,需要时从框架中获取即可。
AOP:Aspect Oriented Prohramming 面向切面编程,将一些公共的功能进行抽取,但是不需要我们在自己的方法中直接显示调用。
一站式框架:Spring本身也提供了数据访问功能和web功能,以及可以很好的管理其他框架。
Spring体系结构
Spring Hello world 搭建
(1)Maven导入spring核心基础jar
<!--spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
(2)编写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">
<bean id="user" class="类的地址"> </bean>
</beans>
(3)编写一个User实体类
public class User {
private String name;
private Integer age;
public User() {
System.out.println("午餐的构造方法");
}
public User(String name, Integer age) {
System.out.println("user有参构造");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
(4)测试spring
//ClassPathXmlApplicationContext("配置文件");负责具体对象管理的实现类
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
User user = applicationContext.getBean("user",User.class);
System.out.println(user);
User user2 = applicationContext.getBean("user",User.class);//通过bean的标识,从Spring容器中获取得到bean
System.out.println(user2);
IOC(反转控制)
是一种设计思想,由原来在程序中手动创建对象的控制权,变为Spring框架来管理。
正控:若要使用某个对象,需要自己去负责对象的创建。
反控:若要使用某个对象,需要从Spring容器中获取需要使用的对象,不关心对象的创建过程,也就是吧创建对象的控制权反转给了Spring框架。
底层实现方式: 解析xml/扫描注解标签 + 工厂模式 + 反射机制
Spring Bean管理
基于xml配置方式
id生成对象名 class类地址 name对象别名,可以有多个
scope:singleton默认的,在Spring中只存在一个bean实例,单例模式
prototype 原型 getBean()时候都会new Bean()
<bean id="user" class="springpro.model.User" scope="prototype">
<property name="name" value="张三"></property>
<property name="age" value="18"></property>
</bean>
xml配置方式依赖注入 DI:Dependency Injection
指Spring创建对象的过程中,将对象依赖属性通过配置设置给该对象
实现IOC需要DI支持
注入的方式
set方法注入
<!--id是注入bean中的名字 property是按照set方式注入 singleton默认单例模式-->
<bean id="user" class="springpro.model.User" scope="singleton">
<property name="name" value="张三"></property>
<property name="age" value="18"></property>
</bean>
构造方法注入
<bean id="user" class="springpro.model.User" scope="prototype">
<constructor-arg name="name" value="李四"></constructor-arg>
<constructor-arg name="age" value="88"></constructor-arg>
</bean>
注解方式的实现
<!--spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
开启注解扫描
<context:component-scan base-package="包名"></context:component-scan>
//注解创建对象
@Component(value = "user")
<bean id = "user" class="类地址"></bean>
Spring JDBC
开发步骤
(1)下载Spring JdbcTemplate的jar包
<!-- spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!-- 阿里数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
(2)导入属性文件
<context:property-placeholder location="classpath:config.properties"/>
(3)管理数据源对象
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driverName}"></property>
<property name="url" value="${urlName}"></property>
<property name="username" value="${uName}"></property>
<property name="password" value="${userPassword}"></property>
<property name="initialSize" value="10"></property>
<property name="minIdle" value="5"></property>
<property name="maxActive" value="20"></property>
</bean>
(4)在配置文件中创建JdbcTemplate
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
(5)在类中获得JdbcTemplate对象,就可以直接使用
@Resource
JdbcTemplate jdbcTemplate;
JdbcTemplate 中常用的方法
execute:无返回值,可执行ddl,增删改语句
update:执行新增、修改、删除语句;
queryForXXX:执行查询相关语句;
AOP面向切面编程
aop是将程序中的非业务代码进行抽取,将非业务逻辑代码与业务代码相隔离,耦合度降低,然后通过一个代理对象在业务代码中调用非业务代码,提高了代码的灵活性。
AOP将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
核心概念
连接点(Joinpoint):类中可以被增强的方法,称为连接点
切入点(pointcut):实际被增强了的方法
通知(advice):方法被增强的功能(比如日志) 分为前置通知,后置通知,异常通知,最终通知,环绕通知
切面:把通知添加到切入点的过程称为切面
目标:代理的目标对象(连接点,切入点所在的类),真正做这件事的类
代理:向目标对象应用通知时创建的代理对象
SpringAOP的实现
下载AOP相关jar
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
xml配置
<bean id="aopdemo" class="com.ff.spring.aop.AopDemo"></bean>
<aop:config>
<!--配置切入点-->
<aop:pointcut expression="execution(*spring.service.UserService.*(..))" id="method"/>
<!--配置通知和切入点-->
<aop:aspect ref="aopdemo">
<aop:before method="savelog" pointcut-ref="adduser"/>
<aop:after method="savelog" pointcut-ref="adduser"/>
<aop:around method="aroundAdvice" pointcut-ref="adduser"/>
<aop:after-throwing method="exceptionAdvice" pointcut-ref="method"
throwing="e"/>
</aop:aspect>
</aop:config>
注解实现
<!--开启自动代理-->
<aop:aspectj-autoproxy> </aop:aspectj-autoproxy>
定义通知
@Component
@Aspect
public class CommonUtil {
//@Before("execution(* com.ffyc.springpro.dao.*.*(..))")
//@After("execution(* com.ffyc.springpro.dao.*.*(..))")
/*@AfterThrowing(value = "execution(* com.ffyc.springpro.dao.*.*(..))",throwing = "e")
public void saveLog(JoinPoint joinPoint,Throwable e){
System.out.println("保存时间:"+new Date()+e.getMessage());
}*/
@Around(value = "execution(*springpro.dao.*.*(..))") //环绕通知
public void saveLog(ProceedingJoinPoint joinPoint){
try{
System.out.println("前置通知");
joinPoint.proceed();
System.out.println("后置通知");
}catch (Throwable e){
System.out.println("异常通知"+e.getMessage());
}
System.out.println("最终通知");
}
}
Spring事物
事物:数据库事物,是属于数据库中的功能。事物可以看做是由对数据库若干操作组成的一个单元。
example:在对数据库进行操作时,任何一步都有可能发生异常,导致后续操作无法完成,前面操作的数据并不可靠,所以需要取消。
事物的作用就是,只要发生异常,就回退到事物开始未进行操作的状态,这些操作要么都完成,要么都取消,保证数据一致性。
那么如何对事物进行管理?主要分为编程式事物和声明式事物。
声明式事物管理:建立在AOP基础上,对方法前后进行拦截,
配置事物管理器
xml配置
<!--配置spring 事务管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
注解实现
<!-- 开启注解事务管理器 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
在service中控制事物
@Service(value = "service")
@Transactional
声明事物不生效的场景
@Transactional 应用在非 public 修饰的方法上
异常被catch捕获导致失效
出现编译期异常
数据库引擎不支持事务
同一各类中,使用非代理对象调用一个有事物的方法,导致事物错误
事物传播行为
至少有俩个东西才能发生传播,指的是当一个事物方法被另一个事物方法调用时,这个事物方法该如何进行。
(1)PROPAGATION_REQUIRED
A方法没有事物,调用B方法,B方法会自己创建一个事物,在事物中运行,B方法出现错误,不影响A方法
A方法有事物,调用B方法,B方法会加入到A方法的事物中,任意一方出现异常,都不会运行
(2)PROPAGATION_REQUIRES_NEW
A方法没有事物,调用B方法,B方法会自己创建一个事物,在事物中运行,B方法出现错误,不影响A方法
A方法有事物,调用B方法,B方法会自己创建一个事物,将A方法事物挂起,A方法出现异常不影响B