目录
Spring是什么
Spring 是一个轻量级的,IOC和AOP的一站式Java 开发框架,是为了简化企业级应用开发而生的。即Spring的作用是简化开发代码。
IOC
即Inversion of Control,缩写为IOC,是由Spring 管理对象,而非传统实现中由程序代码直接操控.
1.Spring基础样式搭建
1.导入Spring依赖
在pom.xml中导入Spring依赖
<!-- spring-context--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.2.RELEASE</version> </dependency>
2.在Spring的xml文件中编写Spring配置文件
其中bean标签中的是配置需要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="adminService" class="com.wjc.springpro.Service.AdminService"> <constructor-arg name="admindao" ref="adminDao"></constructor-arg> </bean> </beans>
在配置中,class是类的地址,id是该类的代称,我们自定义,scope可以配置Spring生成对象的模式
2.配置Spring管理的类
1.直接使用bean标签在spring.xml文件中配置
name是该类的代名,class是类的地址。
如果类中有应用类型变量,则用到ref将该类型变量与他原本类的配置关联起来
2.使用注解
1.开启注解扫描
<context:component-scan base-package="类所在的包名"> </context:component-scan>
开启后,程序会自动扫描指定包(及其子包下的类,并根据注解(如@Component
、@Service
、@Repository
、@Controller
等)将这些类注册为Spring容器中的Bean。
2.进行注解
在需要进行配置Spring管理的类中进行注解,其中@Repsoitory(value="adminDao")就相当于我们在spring.xml文件中写的。
<bean id="adminDao" class="com.wjc.springpro.Dao.AdminDao"></bean>
而Scope注解即是配置其spring生成对象的方式。
Spring会自动将查询结果集映射到相应的实体类对象,并将这些对象返回给调用者,但是如果实体类对象中有其他引用类型的变量时,我们需要在其原本的类中使用Autowried进行注解,或者在xml文件中对两个类进行ref关联,如此在spring给属性赋值的时候就会给类中的引用类型变量赋值。
在给引用类型变量进行赋值的时候,我们可以配置按名字查找这个类,或者按照类型找这个类
1.按类型查找
按类型查找就是图示的方法,在主类和副类加上注解,以及在主类的副类属性上添加Atuowried标签。
2.按名字查找
因为调用的是AdminService类中有AdminDao类的变量,因此我们可以采取按名字查找的方式,在 AdminDao类中为其注解设置名称value在AdminService中使用@Resource(value = "adminDao)或者 @Qualifier(value = "adminDao")加上@Autowired()的组合都可以达到按名字查找的效果
在副类的@respnsitory注解中加上value=“adminDao”,并且在那么我们在@Autowried注解下加上Resource(name="adminDao)就会查找和主类中相对的value值。
注解与 XML 的对比:
注解优点: 方便,直观,高效(代码少,没有配置文件的书写那么复杂)。
注解缺点:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的。
XML优点: 配置和代码是分离的,在 xml 中做修改,打包成jar包之后,仍可以直接对xml文件进行修改。无需编译代码,只需重启服务器即可将新的配置加载。
XML的缺点:编写麻烦,效率低,大型项目过于复杂。
3.配置Spring生成对象的方式
1.scope="singleton",(单例模式)这是spring默认的scope,如此配置,则spring会在运行时生成一个对象, 此后都不在生成,当获得对象时也都是反复在获得最初创建的对象
2.scope="prototype",(原型模式)此配置下,spring每次获得新对象时,都会切实的产生一个新的对象
Spring基础测试
在编写一个实体类并将其配置到spring中后,对其进行测试
再将Admin类配置到spring中后,spring会为我们自动生成Admin类的对象。
1.获得类的对象
我们想要拿到这个对象有以下过程:
1.先使用ApplicationContext对象读取spring.xml文件
2.使用ApplicationContext对象调用getBean方法即可获得对象,具体获得哪个对象,需要我们在getBean方法的参数列表中填写类的id
3.如果我们选择的是单例模式,那么创建的两个Admin对象其实是一个对象,是spring在运行时创建的。如果是原型模式,那么spring初始运行时不会生成对象,而是在getBean()方法被调用的时候创造对象。
2.调用方法
Spring只是简化了开发的过程,获得对象后,调用方法的方式还是和以前一样。
Spring集成mybatis
在pom.xml中导入
spring-context,spring-jdbc,mybatis-spring,mybatis,-mysql,阿里数据源
在spring.xml中配置
生成dao包下所有接口的代理对象
Spring管理SqlSessionFactory
spring管理数据库链接对象
AOP
AOP介绍:
Aspect Oriented programming,面向切面编程,即面向对象编程的补充和延续。AOP的目的就是对程序中的业务代码和非业务代码进行隔离,并在需要非业务代码执行时通过代理对象来进行调用。如此可降低代码的耦合度,提高程序的复用性。
1.AOP的基本概念
连接点(Joinpoint):类中可以被增强的方法,这个方法就被称为连接点(即我们可以简化抽取非业务代码的部分)
切入点(pointcut):类中有很多方法可以被增强,但实际中只有add和update 被增了,那么add和update方法就被称为切入点(实际实现的连接点)
通知(Advice): 通知是指一个切面在特定的连接点要做的事情(增强的功能)。通 知分为方法执行前通知,方法执行后通知,环绕通知等.
目标(Target): 代理的目标对象(连接点,切入点所在类)
代理(Proxy): 向目标对象应用通知时创建的代理对象
综上来看,面向切面编程的思想就是程序中的非业务代码(提交事务,打印日志,权限验证,统一异常处理)从代码中剥离,然后在调用业务代码的时候,通过一个代理对象帮助我们调用这些提取出来的非业务代码。这样一来,业务代码中不会显示非业务代码,却能正常使用这些功能。做到了业务代码和非业务代码的分离,降低了代码的耦合度。
原理:动态代理模式,给业务代码生产代理对象。
1.配置AOP框架
AOP是一种编程思想,很多框架都对他进行了实现,Spring也是其中之一。我们使用时将其jar包导入即可。
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.2.RELEASE</version> </dependency>
2.动态代理示例:
这里在test06中调用AdminService中的方法,AdminService方法中调用AdminDao中的方法,按照spring的结果集自动映射机制,返回的结果会映射在AdminService对应的属性中,而我们在AdminService类中有一个AdminDao类型的属性,对其添加自动注入。
(动态代理对象调用submit方法)
我们希望AdminDao中的方法运行时候可以添加打印日志的功能,于是将打印日志的方法放在commonUtil类中,对其添加Before注解,这样,当执行excution括号中地址中的方法时机会默认执行该方法。
注意:如果没有在AdminService中给AdminDao类配置Spring管理令Spring来创建AdminDao中的对象,而是自己创建AdminDao对象,则无法实现AOP。
五种通知类型
@Before前置通知:方法执行之前
@After后置通知:方法执行之后,无论是否出现异常
@AfterReturnning返回通知:方法成功执行之后通知,出现异常不执行
@AfterThrowing异常通知:抛出异常之后通知
@Around环绕通知:方法执行前后都有通知,可以将前四种的通知全都增添进来
@Around环绕通知示例:
3.spring事物管理
1.数据库事物管理:
数据库事务管理就是对一次数据库操作过程中执行的多条语句进行管理,保证一次对数据库操作过程中多条sql要么都执行成功,要么都不执行,从而确保数据一致性。
比如转账操作,先从A那里扣钱,再向B加钱。如果操作出现异常,为了安全我们应该放弃向数据库提交这两个操作,一旦二者只执行一个,则会造成用户财产的损失。因此我们一定要保持数据的一致性。
2.Spring事物管理
spring事务管理就是spring为程序员的非业务操作进行分离管理(向数据库提交事物,更新数据等),如果程序执行没有问题,那么向数据库提交事物,如果出现问题,则回滚事物,保证数据库数据的准确。
2.1Spring事物管理的两种形式
1.编程式事务在项目中很少使用,这种方式需要在我们代码中需要提交事务或回滚事务时自己写代码实现.
2.2声明式事务管理的使用
声明式事务管理建立在AOP基础上,本质是对方法前后进行拦截,一旦出现异常,则将方法进行截断,并回滚数据。所以声明式事务是方法级的。
实现声明式事务,我们采用注解实现,提供事物管理实现类是DataSourceTransactionManager
在spring.xml文件中配置如下即可:
<!-- 配置spring 事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="druidDataSource"></property> </bean> <!-- 开启注解事务管理--> <tx:annotation-driven transaction-manager="transactionManager"/>
我们可以使用在类或者方法上使用@Transactional标签,即可完成对其的spring事务管理。
在我们的使用逻辑中,一个Sercice层往往会调用多个Dao层的方法,因此,我们对Service层进行事务管理往往效率会更高。
2.3.声明式事务管理的失效
以下情况可能导致事务管理的失效
1.@Transactional 应用在非public修饰的方法上
2.异常被catch捕获导致失效
此处方法里出现了算数异常,但是被catch捕获,导致异常没有传回调用者处,因此Transactional不知道发生了异常,故而向数据库进行了数据提交。没有进行截断。
3.出现编译期异常
此处出现编译器异常usf-2220,Transactional并未回滚数据,而是只将第一组数据提交了。
对于编译器异常导致的声明式事务管理失效,我们可以进行设置防止此问题,默认的rollback等于RuntimeException.class,我们将其修改成Exception.class即可。
4.数据库引擎不支持事务