目录
本篇会进行一些在.xml配置文件开启事务或代理的操作,如遇报错,请鼠标点击IDEA右侧一条条小黄杠中显示红色的杠,选择蓝色文字即可(create namespace declaration)!!!
一、spring框架搭建
1.Spring 是什么
Spring 是一个轻量级的,IOC 和 AOP 的一站式 Java 开发框架,是为了简化企业级应用开发而生的。
2.Spring 体系结构
这里为大家提供Spring官网,供大家详细阅读、了解学习:https://spring.io/https://spring.io/https://spring.io/
3.Spring Hello World 搭建
(1)创建一个JavaEE项目
在pom.xml文件中导入spring核心基础jar包
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
(2)编写spring配置文件
在resources文件夹下创建一个.xml文件,将下面代码复制进去。
<?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="com.ff.spring.model.User"> </bean>
</beans>
(3)编写一个User实体集
public class User{
private String name;
//这里不使用基本类型int,是为了该值默认时与String类型一样,返回null,保持一致
private Integer age;
public void work(){
System.out.println(this.name+"工作");
}
}
(4)测试spring
public class Test {
public static void main(String[] args) {
ApplicationContext applicationcontext=new ClassPathXmlApplicationContext("application.xml");
User user1 = (User) applicationcontext.getBean("user");
User user2 =(User) applicationcontext.getBean("user");
System.out.println(user1);
System.out.println(user2);
}
}
二、IOC(控制反转)
读作“反转控制”(Inverse of Control) 更好理解,不是什么技术,而是一种 设计思想。 就是将原本在程序中手动创建(new)对象的控制权,交由 Spring 框架来管理。IOC 容器负责对象的实例化、对象的初始化,对象和对象之间依赖关系、对象的销毁、对外提供对象的查找等操作,对象的整个生命周期都是由容器来控制。所以通俗来说, IOC:让spring框架创建对象,同时进行依赖注入。
正控:
若要使用某个对象,需要
自己去负责对象的创建
|
反控:
若要使用某个对象,只需要
从 Spring 容器中获取需要使用的对象,
不关心对象的创建过程
,也就是把
创建对象的控制权反转给了 Spring 框架.
|
为了实现这种反控思想,就需要通过Spring Bean 管理实现。
1.基于xml配置方式实现
在spring配置文件注册需要spring框架管理的类:
(1)用bean标签配置需要框架管理的类,其中各属性含义:
id="对象名称,在getBean获得spring生成的对象"
class="要spring管理的类的地址"
scope=" "配置bean作用域 默认为singleton(单例的)
scope="singleton" singleton(单例的)即spring框架启动时只创建一个对象 |
scope="prototype" prototype 原型的(多例的)即每次获得对象时,创建一个新对象. |
依赖注入(DI):创建对象时,为对象属性赋值。而依赖注入又分为两种方式。
(1)通过属性set方法注入
<!--id是对象名,class是对象所属类路径property标签里分别是类的属性和set的值 -->
<bean id="admin" class="com.springpro.model.Admin" scope="prototype">
<property name="account" value="admin"></property>
<property name="password" value="111"></property>
</bean>
(2)通过构造方法注入
<!--有参构造赋值-->
<bean id="admin" class="com.springpro.model.Admin" scope="prototype">
<constructor-arg name="account" value="admin"></constructor-arg>
<constructor-arg name="password" value="111"></constructor-arg>
</bean>
2.注解方式实现
(1)开启spring注解扫描
在.xml配置文件中输入以下配置,扫描指定的包。这里推荐写入类似如图红框中最大的文件夹名,以便在各处随时进行注解操作。
<context:component-scan base-package="包名"> </context:component-scan>
(2)注解创建对象
@Component(value=“user”)
|
适用于模型类,写在类名之上,等于 <bean id=“user” class=“”></bean>
|
@Service
|
适用于Service层,写在类名之上 |
@Repository
|
适用于Dao层,用于创建需要调用的Dao层对象 |
@Scope(value=“prototype”)
|
原型(每获得对象,创建一个对象)
|
@Scope(value=“ singleton ”)
|
单例(只创建一个对象)
|
依赖注入(DI):创建对象时,为对象属性赋值。
@Autowired
Spring 提供的注解,可以写在字段和 setter 方法上。如果写在字段上,那么就不需要再写 setter 方法。默认情况下它要求依赖对象必须存在,如果允许 null 值,可以设置它的 required 属性为 false。
该自动注入有两种值的匹配方式:
- 通过属性类型查找(@Autowired)
- 通过对象名称查找(配合@Qualifier标签使用)
@Resource
该注解标签也是添加到属性上的,注入值不能为空,可通过类型查找
xml 优点
|
配置和代码是分离的,在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载
|
xml 缺点
|
编写麻烦,效率低,大型项目过于复杂
|
注解优点
|
方便,直观,高效(代码少,没有配置文件的书写那么复杂)
|
注解缺点
|
以硬编码的方式写入到 Java 代码中,修改需要重新编译代码
|
三、前后端交互配置
1.Spring数据访问层管理
Spring 是个一站式框架:Spring 自身也提供了 web 层的 SpringWeb 和持久层的 Spring JdbcTemplate。
(1)下载 Spring jdbc 数据访问层 jar 包,在pom.xml文件中配置
<!-- 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)在.xml配置文件中导入属性文件
<context:property-placeholder location="config.properties"/>
(3)管理数据源对象
spring管理数据库连接对象,这里采用阿里巴巴数据库连接对象
value值根据各自电脑与数据库连接情况自行填写
<bean id="dataSource"class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value=""></property>
<property name="url" value=""></property>
<property name="username" value=""></property>
<property name="password" value=""></property>
<property name="initialSize" value="10"></property><!--初始化连接数量-->
<property name="maxActive" value="20"></property><!--最大连接数量-->
</bean>
2.Spring集成Mybatis
(1)Spring下载mybatis插件包,在pom.xml文件中配置
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
(2)配置 sqlSessionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="mapperLocations" value="classpath:mappers/*Mapper.xml">
</property>
</bean>
(3)指定生成接口代理
<bean id="mapperFactory" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ffyc.ssm.dao"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">
</property>
</bean>
四、AOP(面向切面编程)
1.AOP概述
AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程,通过 预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。
AOP 是 OOP 的延续,是软件开发中的一个热点,是 java 开发中的一个重要内容。利用 AOP 可以对业务逻辑和非业务逻辑进行隔离,从而使得各部分之间的 耦合度降低,提高程序的可重用性,同时提高了开发的效率。
注:AOP是Java中的编程思想,spring只是使用了这种编程思想。
连接点(Joinpoint): 类中可以被增强的方法,这个方法就被称为连接点.切入点(pointcut): 类中有很多方法可以被增强,但实际中只有 add 和 update被增了,那么 add 和 update 方法就被称为切入点(实际实现的连接点).通知(Advice): 通知是指一个切面在特定的连接点要做的事情(增强的功能)。通知分为方法执行前通知,方法执行后通知,环绕通知等.目标(Target): 代理的目标对象(连接点,切入点所在类).代理(Proxy): 向目标对象应用通知时创建的代理对象.
2.Spring框架的AOP实现
<!--下载AOP相关jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
3.AspectJ 中常用的通知有五种类型
这些通知都是在操作非业务逻辑,这里以一些类中方法为例。
启动 AspectJ 支持:(在.xml配置文件中配置)
<!--开启自动代理-->
<aop:aspectj-autoproxy />
(1)@Before
前置通知:业务方法执行之前调用执行
//业务方法
public void insert(){
System.out.println("插入");
}
public void delete(){
System.out.println("删除");
}
//非业务方法
@Before("execution(* com.springpro.dao.AdminDao.*(..))")
public void printLog(){
System.out.println("打印日志");
}
测试结果:
(2)@After
后置通知:业务方法执行之后调用执行(即使业务代码中出现异常也会继续执行相应的非业务代码)
代码只是把 @Before换成@After,其余一致:
但其中代码有异常,还是会执行完异常前的部分
//业务方法
public void insert(){
System.out.println("插入");
System.out.println(10/0);//除数不能为0
}
public void delete(){
System.out.println("删除");
}
测试结果:
(3)@AfterReturnning
返回通知:业务方法执行之后调用执行(业务代码中出现异常不会继续执行相应的非业务代码)
代码只是把 @After换成@AfterReturnning,其余一致:
(4)@AfterThrowing
异常通知:业务代码出现异常执行
//业务方法
public void insert(){
System.out.println("插入");
System.out.println(10/0);//除数不能为0
}
public void delete(){
System.out.println("删除");
}
//非业务方法
@AfterThrowing(value = "execution(* com.springpro.dao.AdminDao.*(..))",throwing = "throwable")
public void exception(Throwable throwable){
System.out.println("系统忙"+throwable.getMessage());
}
不会再继续执行后面代码 :
(5)@Around
环绕通知:在业务代码方法执行前,后,出现异常时添加功能
//业务方法
@Autowired
JdbcTemplate jdbcTemplate;
public void insert(){
System.out.println("插入");
jdbcTemplate.update("insert into admin(account,password,gender)values(?,?,?)","张三","888","男");
System.out.println(10/0);
jdbcTemplate.update("insert into admin(account,password,gender)values(?,?,?)","李四","999","男");
}
public void delete(){
System.out.println("删除");
}
//非业务方法
@Around(value = "execution(* com.springpro.dao.AdminDao.*(..))")
public void around(ProceedingJoinPoint joinPoint){
try {
System.out.println("前置通知");
Object[] objects = joinPoint.getArgs();//获取目标方法的参数
System.out.println(Arrays.toString(objects));
Object object = joinPoint.proceed();//调用目标业务方法
System.out.println("返回通知");
}catch (Throwable throwable){
throwable.printStackTrace();
System.out.println("异常通知");
}
System.out.println("后置通知");
}
因为异常只能插入第一条信息,上面代码打印的地方代表响应通知会执行的位置
除去中间的异常报错,完整打印结果如图:
五、Spring事务管理
数据库事务管理 :就是对 一次数据库操作 过程中执行的 多条语句 进行管理,保证一次对数据库操作过程中多 条 sql 要么都执行成功,要么都不执行 ,从而 确保数据一致性 .Spring 事务管理 :就是 spring 框架针对程序中提交事务这部分 非业务代码进行分离管理 , 减轻程序员负担.在 程序执行没有问题 时, 提交事务 , 出现问题 时, 回滚事务 .
1.Spring 中的事务管理形式
编程式事务
|
在项目中很少使用,这种方式需要在我们代码中需要提交事务或回滚
事务时自己写代码实现
|
声明式事务
|
管理建立在 AOP 基础上,本质是对方法前后进行拦截,所以声明式
事务是方法级别的
|
2.基于注解实现的 spring 事务管理
(1)配置事务管理器
在.xml配置文件中输入
<!-- 配置 spring 事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
(2)注解方式
<!-- 开启注解事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
(3)使用方法
@Transactional 可添加到方法上,也可加在类上,则类中所有方法都在spring事务管理中
该标签保证了所有sql同时执行或同时不执行,保持数据一致性。防止出现上面通知标签中代码中存在异常但还是执行了异常前一部分的情况,这在实际开发中会带来巨大灾难!
(4)声明式事务不生效的场景
声明式事务不生效的场景:(@Transactional)不生效:
1.@Transactional 被应用在非 public 修饰的方法上
2.方法中的异常被 catch 捕获,spring认为该方法没异常,只提交了一部分数据,导致事务失效
3.出现编译期异常,如下面的test3,编码格式有问题,但数据库还是会收到test1的信息,但只要使用@Transactional(rollbackFor = Exception.class),就可使其回滚
4.数据库引擎不支持事务,mysql中只有innodb引擎支持事务
//业务方法
public void test1(){
jdbcTemplate.update("insert into admin(account,password,gender)values(?,?,?)","张三","888","男");
}
public void test2(){
jdbcTemplate.update("insert into admin(account,password,gender)values(?,?,?)","李四","999","男");
}
//非业务方法
public void test3() throws UnsupportedEncodingException {
adminDao.test1();;
"aa".getBytes("utf-8888");
adminDao.test2();
}
以上就是关于spring的入门基础知识了,在接下来的文章中,我将继续为大家分享有关spring框架的知识,看看spring框架是如何做到称为Java开发社区最受欢迎的框架之一的!!!