Spring
概述
Spring是一个轻量级的IOC和AOP的一站式Java开发框架,其简化了企业级开发。
轻量级:框架体积小(核心模块)
IOC:Inversion of Control 控制反转,把创建对象的控制权,管理权交给spring框架
AOP:Aspect Oriented Programming 面向切面编程,将程序中公共的非业务代码分离提取出来
一站式:处理IOC和AOP之外,还对数据访问层、web层都有封装
配置
1、导入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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.xhz.spring.model.Admin"> </bean></beans>
3、创建实体类Admin
4、测试
ApplicationContext applicationContext=newClassPathXmlApplicationContext("springpro.xml");
Admin admin = (Admin)applicationContext.getBean("admin");
Admin admin1 = applicationContext.getBean("admin",Admin.class);
System.out.println(admin);
System.out.println(admin1);
System.out.println(admin == admin1);//true
IOC-控制反转
IOC:Inversion of Control 控制反转,把创建对象的控制权,管理权交给spring框架。
IOC可以看作一个容器,spring框架也可称为spring容器或IOC容器,主要负责对象的实例化、对象的初始化,对象和对象之间依赖关系、 对象的销毁、对外提供对象的查找等操作,对象的整个生命周期都是由容器来 控制。
spring bean管理
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
<!--在spring配置文件注册需要Spring框架管理的类使用bean标签配置需要spring管理的类id="对象名称,可以用getBean()获得spring生成的对象"class="需要spring管理类的地址"name="对象的别名" scope="配置bean的作用域"常用的作用域:singleton 单列(默认) 在spring框架启动时,创建唯一的一个对象prototype 原型(多例) 在每次获得对象时,创建一个新的对象request 在每次http请求时创建一个对象,仅用于WebApplicationContext环境--><!-- 生成的对象名 对象的全类名 --><bean id="admin" class="com.xhz.spring.model.Admin" scope="prototype"></beans>
依赖注入
xml配置方式注入
<!-- 依赖注入:创建对象时,对象中属性赋值1、通过属性set方法注入2、通过构造方法注入--><!-- 通过属性set方法注入 --><property name="account" value="admin"></property><property name="password" value="123"></property>
<!-- 通过构造方法注入 --><constructor-arg name="account" value="admin"></constructor-arg><constructor-arg name="password" value="123"></constructor-arg></bean>
<bean id="adminDao" class="com.xhz.spring.dao.AdminDao"></bean>
<bean id="adminService" class="com.xhz.spring.service.AdminService"><!-- 类中属性的名字 调用那个类就是那个类bean的id --><property name="adminDao" ref="adminDao"></property></bean>
注解方式注入
开启注解扫描
<?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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描 指定扫描的包 --><context:component-scan base-package="com.xhz.spring"> </context:component-scan>
</beans>
常用的注解
//等同于xml中的<bean id="admin" class="com.xhz.spring.model.Admin" scope="prototype">
@Component(value = "admin")
@Scope(value = "prototype")
//通常给Dao层
@Repository(value = "adminDao")
/** 注解方式注入,前提是要在AdminDao处配置@Repository(value = "adminDao")* 自动注入,用于属性和属性set方法上,若在属性上可不写set方法* 默认情况下,注入的值不能为空 required= true* @Autowired spring提供* 自动注入有两种匹配方式* 1、通过属性类型查找 @Autowired* 2、通过对象名字查找 @Qualifier(value="adminDao")** @Resource java提供,添加在属性上,可不写set方法* 1、通过属性类型查找 @Resource* 2、通过对象名字查找 @Resource(value="adminDao")* */
xml和注解的区别
xml
优点:配置和代码是分离的,在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载
缺点:编写麻烦,效率低,大型项目过于复杂
注解
优点:方便,职直观,高效
缺点:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的
数据访问层
由于Spring是一站式的一种框架,自然对web层和持久层也进行了封装。
配置
1、首先导入所需的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>
<!-- spring集合mybatis jar包 -->
<!-- Spring 集成 Mybatis 其核心是将 SqlSessionFactory 交由 Spring 管理,并由Spring 管理对 dao 接口的代理实现
-->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.1</version>
</dependency>
<!-- spring-context -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.2.RELEASE</version>
</dependency>
<!-- 配置mysql -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version>
</dependency>
<!-- Mybatis -->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.2</version>
</dependency>
2、创建配置xml文件
2·1、mybatis文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- mybatis全局核心配置文件 --><settings><!-- 配置日志 --><setting name="logImpl" value="STDOUT_LOGGING"/><setting name="mapUnderscoreToCamelCase" value="ture"/><!-- 开启二级缓存 --><setting name="cacheEnabled" value="true"/></settings>
<!-- 为类配置别名 --><typeAliases><package name="com.xhz.ssm.model"/></typeAliases>
</configuration>
2·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"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描 指定扫描的包 --><context:component-scan base-package="com.xhz.ssm"> </context:component-scan>
<!--阿里巴巴数据库连接管理对象,负责生成数据库连接对象,以及提供数据库连接池归功能让spring来管理阿里巴巴数据库连接对象--><bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property><property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai"></property><property name="username" value="root"></property><property name="password" value="root"></property><property name="initialSize" value="10"></property><!--初始化连接数量--><property name="maxActive" value="20"></property><!--最大连接数量--></bean>
<!-- spring管理生成SqlSessionFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="druidDataSource"></property><!-- 注入数据源 --><!-- mybatis配置文件 --><property name="configLocation" value="classpath:mybatis.xml"></property><!-- 扫描mapper映射文件 --><property name="mapperLocations" value="classpath:mappers/*Mapper.xml"> </property></bean>
<!-- 生成dao层下的接口代理对象 --><bean id="mapperFactory" class="org.mybatis.spring.mapper.MapperScannerConfigurer"><!-- 指定接口所在的包 --><property name="basePackage" value="com.xhz.ssm.dao"></property><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property></bean>
</beans>
AOP
概述
aop:Aspect Oriented Programming,面向切面编程,是对oop面向对象编程的延续;
主要思想是通过动态代理模式把非业务代码(eg:提交事务,打印日志,权限验证,异常处理)提取分离出来;
然后在调用业务代码时,通过生成一个代理对象来调用非业务代码;
这样就能将业务代码和非业务代码分离开来,降低了代码的耦合度
基本概念
连接点:Joinpoint 类中可以被增强的方法
切入点:pointcut 实际被增强的方法只有add和update
通知:Advice 指切面在特定的连接点要执行的增强的功能
目标:Target 代理的目标类,连接点和切入点所在的类
代理:Proxy 向目标对象应用通知时创建的代理对象
实现
AspectJ 是一个基于 Java 语言的 AOP 框架,支持注解式开发。
1、首先需配置AOP依赖的jar包
<!-- pom.xml -->
<!-- spring-AOP依赖的jar -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.2.RELEASE</version>
</dependency>
<!-- spring全局配置 -->
<!-- 基于注解方式的实现 启动 AspectJ 支持:-->
<aop:aspectj-autoproxy />
AspectJ 常用注解
/*
* 通知;向连接点添加的功能
* @Before 前置通知:方法执行之前调用
* @After 后置通知:方法执行之后调用,无论是否出现异常
* @AfterReturning 返回通知:方法成功执行之后调用,出现异常不执行
* @AfterThrowing 异常通知:抛出异常之后调用
* @Around 环绕通知:方法执行前后都有调用* */
/*
* execution(* com.demo.test *.*(..))
*按顺序自左向右:
* execution 为主体
* 第一个 * 的位置表示返回类型,此处为 * 则表示为任意类型
* com.demo.test 表示拦截的包名
* 第二个 * 的位置表示类名,此处为 * 则表示为包中所有类
* 第三个 * 的位置表示方法名,此处为 * 则表示类中所有方法
* (..)中表示方法的参数,". ." 为任意参数
* */
@After(value = "execution(* com.xhz.spring.dao.AdminDao.*(..))")public void after(){System.out.println("After");}
@AfterThrowing(value = "execution(* com.xhz.spring.dao.AdminDao.*(..))",throwing = "throwable")public void exception(Throwable throwable){System.out.println("exception");}
@Before(value = "execution(* com.xhz.spring.dao.AdminDao.*(..))")public void before(){System.out.println("before");}
@AfterReturning(value = "execution(* com.xhz.spring.dao.AdminDao.*(..))")public void afterReturning(){System.out.println("afterReturning");}
@Around(value = "execution(* com.xhz.spring.dao.AdminDao.*(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("前置通知");try{proceedingJoinPoint.proceed();//调用目标方法
System.out.println("返回通知");}catch (Throwable t){t.printStackTrace();System.out.println("异常通知");}System.out.println("后置通知");}
事务管理
来源
事务这一概念本质上是数据库提供的一种管理机制。
即对一次数据库操作中的多条sql语句,要么都成功执行,要么都不执行。
以转账为例:A账户转账-500¥,B账户+500¥,其中任一sql出错都导致其余sql无法执行。
此时由于业务逻辑尚未完成,为了保证数据一致性,程序要进行回退。
而数据库事务的作用就是保证每一个操作都是成功执行的,一旦有执行失败的操作,此次的操作就会强制被程序回退到没有出现问题的时候,从而满足数据一致性。
概述
spring事务管理是spring框架对事务提交这一功能进行封装,在开发过程中不需要手动提交。
在程序执行没有问题时,提交事务;出现问题时,回滚事务。
管理方式
spring事务管理方式有两种:
1、编程式管理:需要程序员在代码中自行提交事务以及回退程序
2、声明式管理:使用了AOP思想,可以为方法前后进行拦截,是方法级别的
2·1、配置spring事务管理器
<!-- 配置 spring 事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启注解事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
2·2、例
/*
* @Transactional添加在方法上
* 表示改方法会被spring管理
*
* @Transactional也可以添加类上
* 此类这所有方法都会被spring管理
*
* 声明式事务管理失效的场景:
* 1、应用在非public修饰的方法上
* 2、异常被catch捕获,出现认为没有异常会提交事务
* 3、方法中出现了编译期异常,解决方法:@Transactional(rollbackFor = Exception.class)
* 4、数据库引擎不支持事务管理,mysql中只有innodb支持事务
* */