Spring
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
Spring Frameork:
7大模块
两大核心:IOC(控制反转)和AOP(面向切面编程)
IOC(控制反转)
控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
硬编码,耦合度相当高
UserService----》setUserDao() new UserDaoImpl1
ResultService----》setUserDao() new UserDaoImpl1
工厂:根据需要返回不同的实例对象
spring容器(工厂模式):托管对象
控制反转:创建对象的权利从程序员的手中交给了spring
IOC(控制反转):实现方式(DI,依赖注入)
搭建环境:
导入spring Web MVC
创建applicationContext.xml
测试:
//解析配置文件
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationConext.xml");
//得到bean实例
StudentService studentService=applicationContext.getBean("studentService",StudentService.class);
studentService.getStudentName();
applicationContext.xml
< bean> : 创建实例
< alias>:别名
< import>:导入其他xml文件
DI(依赖注入)
set注入
构造器注入
集合注入(list,set,map)
数组组入
properties注入
p命名空间和c命名空间注入,需要导入命名空间
xmlns:p=“http://www.springframework.org/schema/p”
xmlns:c=“http://www.springframework.org/schema/c”
空值注入
作用域:
单例:适合单线程或用户少的情况
prototype:适合多线程的情况
注解:
注解分类:
内建注解(JDK自带)
@Override:表示该方法是重写父类的某个方法
元注解:
@Target:作用域
@Retention(RetentionPolicy.RUNTIME)
source:在源码显示,编译时丢弃
Class:编译时会记录到Class中,运行时忽略
RunTime:运行时存在,可以通过反射读取
@Inherited:允许子类继承注解,只继承类上面的注解
@Documented 生成javaDoc时会包含注解
自定义注解规则:
使用@interface关键字定义注解
访问注解信息的3个方法
getAnnotation():返回程序元素上存在的指定类型的注解
getAnnotations():返回程序元素上存在的所有注解
isAnnotationPresent():用来判断该程序元素上是否包含指定类型的注解
AOP
AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 …
切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
目标(Target):被通知对象。
代理(Proxy):向目标对象应用通知之后创建的对象。
切入点(PointCut):切面通知 执行的 “地点”的定义。
连接点(JointPoint):与切入点匹配的执行点。
aop的依赖包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
先编写我们的业务接口和实现类
public interface UserService {
public void add();
public void delete();
public void update();
public void search();
}
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void update() {
System.out.println("更新用户");
}
@Override
public void search() {
System.out.println("查询用户");
}
}
前置增强 后置增强:
public class Log implements MethodBeforeAdvice {
//method : 要执行的目标对象的方法
//objects : 被调用的方法的参数
//Object : 目标对象
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println( o.getClass().getName() + "的" + method.getName() + "方法被执行了");
}
}
public class AfterLog implements AfterReturningAdvice {
//returnValue 返回值
//method被调用的方法
//args 被调用的方法的对象的参数
//target 被调用的目标对象
@Override
public void afterReturning(Object returnValue, Method method, Object[] args,Object target) throws Throwable {
System.out.println("执行了" + target.getClass().getName()
+"的"+method.getName()+"方法,"
+"返回值:"+returnValue);
}
}
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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册bean-->
<bean id="userService" class="com.kuang.service.UserServiceImpl"/>
<bean id="log" class="com.kuang.log.Log"/>
<bean id="afterLog" class="com.kuang.log.AfterLog"/>
<!--aop的配置-->
<aop:config>
<!--切入点 expression:表达式匹配要执行的方法-->
<aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
<!--执行环绕; advice-ref执行方法 . pointcut-ref切入点-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
自动装配
xml显示配置:autowire=“byType/byName”
注解
@Autowired(required=false) 属性值可以为空
@Autowired 按照类型自动装配,注解属于spring
@Autowired @Qualifier(“userDao”) 指定名称装配
@Resource 默认按照名称装配,找不到按照类型装配
@Resource(name=“userDao”)指定名称装配
@component
//衍生注解,会按照mvc三层架构分层
@Respository 标识Dao
@Service 标识service
@Controller 标识Controller
javaConfig
javaconfig是spring的一个子项目,spring4之后成为了核心功能
@Configuration
@ComponentScan(“com.qiku.spring”)
public class MyConfig {
@Bean
public Student stu(){
return new Student();
}
}
代理:
静态代理
抽象角色(接口) 真实角色(目标类) 代理角色(代理类)
jdk动态代理
动态生成代理类,可以为不同的目标类提供代理
AOP相关术语
增强处理(Advice)
前置增强 后置增强
环绕增强、异常抛出增强、
最终增强等类型
切入点(Pointcut):要增强的位置(表达式,查询条件)
连接点(Join Point):通过表达式找到的具体增强的代码位置
切面(Aspect):由增强处理和切入点共同组成
目标对象(Target object):被增强的目标类
AOP代理(AOP proxy):代理类
织入(Weaving):将增强处理增强到指定位置的情况
spring实现AOP:
1、引入织入依赖
org.aspectj
aspectjweaver
1.9.5
2、xml导入aop约束
3、启用AOP注解
< aop:aspectj-autoproxy/>
4、xml配置
使用原生springAPI
< aop:config>
<!-- 切入点, 访问修饰符 返回值 类名 方法名(参数)-->
<aop:pointcut id="poincut" expression="execution(* com.qiku.spring.service.impl.StudentServiceImpl.*(..))"/>
<!-- 织入-->
<aop:advisor advice-ref="beforeLog" pointcut-ref="poincut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="poincut"/>
</aop:config>
自定义类实现
<aop:congfig>
<aop:pointcut id="pointcut" expession="excution(表达式)"/>
<!--织入 -->
<aop:aspect ref="logger">
前置: <aop:before method="" pointcut-ref="pointcut">
后置: <aop:after-returning method="" pointcut-ref="pointcut" returning="result">
抛出异常: <aop:after-throwing method="" pointcut-ref="pointcut" throwing="e">
最终: <aop:after method="" pointcut-ref="pointcut">
环绕: <aop:around method="" pointcut-ref="pointcut" />
</aop:aspect>
</aop:congfig>
spring-mybatis整合
1、导入依赖: spring-mybatis
junit mybatis mybatis-jdbc springwebmvc aop织入 log4j 注解
设置资源过滤
2、引入properties文件、mybatis-config文件、log4j文件、applicationContext.xml文件
3、编写三层架构
4、xml文件配置
datasoure数据源
sqlsessionFactory
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/qiku/studentsys/dao/*.xml"/>
<property name="typeAliasesPackage" value="com.qiku.studentsys.pojo"/>
sqlsessionTemplate/MapperFactoryBean/MapperScannerConfigurer
5、spring引入外部properties文件
<context:property-placeholder location=“classpath:database.properties”/>
database.properties 里面 username 必须用 jdbc.username. 否则username就变成了系统管理员的名字。
事务四个特性ACID:原子性 一致性 隔离性 永久性
spring事务管理
声明式事务
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--配置哪些方法使用什么样的事务,配置事务的传播特性-->
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="search*" propagation="REQUIRED"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.chen.dao.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
spring事务传播特性:
事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。spring支持7种事务传播行为:
- propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。
- propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
- propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
- propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
- propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
- propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作
Spring 默认的事务传播行为是 PROPAGATION_REQUIRED,它适合于绝大多数的情况。
name 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
propagation 事务的传播行为,默认值为 REQUIRED。
isolation 事务的隔离度,默认值采用 DEFAULT。
timeout 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
read-only 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
rollback-for 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。no-rollback- for 抛出 no-rollback-for 指定的异常类型,不回滚事务。事务隔离级别:https://www.cnblogs.com/wj0816/p/8474743.html
DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
未提交读(read uncommited) :脏读,读取了其他事务未提交的数据,不可重复读,虚读都有可能发生已提交读 (read commited):避免脏读。发生了在一个事务内两次读到的数据是不一样,但是不可重复读和虚读有可能发生
可重复读 (repeatable read) :避免脏读和不可重复读.但是虚读有可能发生.
不可重复读的重点是修改 :
同样的条件 , 你读取过的数据 , 再次读取出来发现值不一样了
幻读的重点在于新增或者删除
同样的条件 , 第 1 次和第 2 次读出来的记录数不一样
串行化的 (serializable) :避免以上所有读问题.
Mysql 默认:可重复读
Oracle 默认:读已提交
使用注解:
<!-- 使用annotation定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
springMVC
1、引入servlet-api springWebMvc jsp-api
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
2、注册DispatcherServlet
<servlet>
<servlet-name>springmvc</servlet-name>
<!--核心控制器,拦截所有请求进行分发-->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>