一、Spring了解

Spring:程序员们的春天

  • Spring主要技术是IOC、AOP两个大概念
  • 它是轻量级的,每个jar包就1M ~ 3M 左右,所以速度快
  • 面向接口编程:降低了耦合度
  • 面向切面编程:增加了灵活性
  • 不排斥其它框架,可以和任何框架整合到一起

二、IOC入门

2.1 IOC概念

IOC:控制反转,是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入,还有一种方式叫“依赖查找”。

IOC是一种设计思想,其实我们在学习Spring的时候,应该把注意力放在Spring的设计方式上,为什么要这么设计,这么设计的思想是什么。

控制反转:原本我们程序员需要自己new Student一个对象,但是现在反转了,我们将new Student这种操作交给Spring容器去处理,这就是控制反转,以后不需要我们手动的去new对象了

依赖注入:依赖注入就是我们在创建了对象以后,肯定要给对象的属性赋值啊,这种赋值的操作就是依赖注入,只是我们的赋值方式和以往略有不同。

2.1 创建对象

  • 使用xml方式,通过bean标签来创建对象
<bean id="stu" class="com.meteor.pojo.Student"></bean>
这就相当于我们的 Student stu = new Student(); 已经创建出来了对象
id:是对象的名称
class:是对象类
//这就相当于我们把对象交给了spring容器处理,想用的时候就去容器种拿
  • 我们来取一下对象,看看是如何使用的
//1.通过读取配置文件中的bean标签信息,已经创建出了对象 相当于Student stu = new Student();
//当读取applicationContext.xml配置文件信息时,会将其所有bean标签的对象都创建出来
ApplicationContext cpx = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过bean标签中的id拿到对象
Student stu = (Student) cpx.getBean("stu");

2.2 使用setter赋值

  • 我们的类对象,必须有set()方法
  • 必须拥有无参构造方法
  • 我们用的标签是property

简单类型的注入:

<!-- 创建学生对象 -->
<bean id="stu" class="com.meteor.pojo.Student">
<property name="name" value="张三"/>
<property name="age" value="21"/>
</bean>

引用类型的注入:

<!-- 创建学生对象 -->
<bean id="stu" class="com.meteor.pojo.Student">
<property name="name" value="张三"/>
<property name="age" value="21"/>
<property name="school" ref="sch"/>
</bean> <bean id="sch" class="com.meteor.pojo.School">
<property name="name" value="hljdx"/>
<property name="address" value="hlj"/>
</bean>
// 我们将Student、School两个对象都交给了spring容器管理,而引用类型的注入方式是通过ref属性,将school这个对象传到student里面

2.3 使用构造方法注入

  • 必须拥有构造方法,你构造方法是几个参数,注入就几个参数
  • 无需强制set()方法
  • 我们用的标签是constructor-arg
<!-- 创建学生对象 -->
<bean id="school" class="com.meteor.pojo2.School">
<--!--> name是构造方法的名称 </--!-->
<constructor-arg name="name" value="hljdx"/>
<constructor-arg name="address" value="hlj"/>
</bean>
  • 也可以通过参数下标来注入
<bean id="stu" class="com.meteor.pojo2.Student">
<constructor-arg index="0" value="hljdx"/>
<constructor-arg index="1" value="20"/>
<constructor-arg index="2" ref="school"/>
</bean>

2.4 引用类型自动注入

刚刚我们已经介绍了引用类型通过ref属性注入,但是还可以通过另两种方式

byName:按照变量名称注入,spring容器会根据你原本类中的引用类型 public School school 这个school名称,自动去xml文件中搜索有没有这个同名id,如果有则进行注入。

byType:按照变量类型注入,spring容器会自动寻找School类型的class,一种类型只有一个对象。

  • java类中的成员变量的类型与xml文件中bean对象的类型一样

  • java类中的成员变量的类型与xml文件中bean对象的是父(java)子(xml)类型

  • 若子类父类用默认得名称,则父类先注入。子类的构造方法会默认调用父类无参构造方法,清空数据嘛,然后再调用自己的构造方法。若子类父类改名了,则按名称注入。

  • java类中的成员变量的类型与xml文件中bean对象的类型是接口(java)与实现类

2.5 使用注解一体化IOC

//使用注解必须在xml文件中配置注解扫描器
<context:component-scan base-package="com.meteor.pojo3"/>

控制反转

  • 我们使用xml时通过bean标签来创建对象,现在使用注解来代替
@Component
public class Student {
// 当我们在类上加入这个注解的时候,就相当于将对象放入了spring容器进行管理。但是此时并没有进行赋值操作,
如果我们不加入名称,则默认使用的是驼峰命名法 //并且Spring创建的对象是单例模式,无论我们使用多少次都是相同的对象

@Component: 可以创建任意对象

@Controller: 专门创建控制器的对象(Servlet),接受用户请求返回处理结果给客户端

@Service: 专门用来创建业务逻辑对象,访问数据层,处理完毕后返回给界面层

@Repository: 用来创建数据访问层的对象,负责增删改查


依赖注入

@Value: 给简单类型注入值

@Autowired: 使用类型注入值,从整个Bean工厂中搜索同源类型的对象,进行注入

@Autowired + @Qualifier : 使用名称注入值,如果单独使用Qualifier 是不会注入进来值得

@Resource: 自动注入,我个人挺喜欢用这个先按名称匹配,再按类型匹配Bean。


三、AOP入门

3.1 AOP概念

AOP: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AOP面向切面编程,一般将公用的代码放入到切面中,例如日志、事务等等,减少了冗余的代码,降低了程序的耦合度。

3.2 常用AOP通知

  • 切面:就是将重复的、可复用的代码提取出来

  • 连接点:就是目标方法,因为我们需要知道是在目标方法 前 切面还是 后 切面

  • 切入点:多个连接点构成了切入点

  • 通知:指定切入时机

  • 在Advice的时间,在Pointcut的位置,执行Aspect

  • @Before:前置通知,在目标方法之前执行,只能拿到目标方法的签名

  • @AfterRetunring:后置通知,在目标方法后执行,可以修改目标方法的返回值

  • @Around:环绕通知,这个最厉害,相当于前两者的结合,但是略有不同

  • @After:最终通知,无论程序挂没挂,这个都必须执行,一般用于释放资源

  • @AfterThrowing:异常通知,在目标方法执行发生了异常的时候,执行这个通知、

  • 公式:execution(访问权限、返回类型、方法声明(参数))

  • 在xml文件中加入切面的注解

<aop:aspectj-autoproxy/>

3.3 Before前置通知

@Aspect
public class MyAspect {
//定义方法,表示切面的具体功能
/*
前置通知方法的定义
1)方法是public
2)方法是void
3)方法名称自定义
4)方法可以有参数,如果有是JoinPoint
@Before:前置通知
属性:value切入点表达式,表示切面的执行位置。
在这个方法时,会同时执行切面的功能
位置:在方法的上面
特点:
1)执行时间:在目标方法之前先执行的
2)不会影响目标方法的执行
3)不会修改目标方法的执行结果
*/
@Before(value = "execution(public void com.meteor.service.impl.SomeServiceImpl.doSome(String, Integer))")
public void myBefore() {
System.out.println("前置通知,切面的功能在目标方法之前执行" + new Date());
}
}
//可以拥有一个方法参数JoinPoint jp,用来获取方法签名

3.4 @AfterRetunring后置通知

//通过returning来指定方法返回值得名称,必须与接收名称相同
//如果说我们传的是基本类型则无法改变结果,如果传的是引用类型则可以通过值进行修改。
@AfterReturning(value = "execution(* *..SomeServiceImpl.doOther(..))",returning = "res")
public void myAfterReturning(Object res) {
System.out.println("后置通知,在目标方法后执行的。" + res);
}

3.5 @Around环绕通知(最重要)


* *..service.*.*(..)
代表任意权限方法下的 任意包下的 service包 下的 任意类中的任意方法的任意参数 // 返回类型推荐使用Object或者*
@Aspect
public class MyAspect {
@Around(value = "execution(* *..SomeServiceImpl.doFirst(..))")
public Object myAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("执行了myAround" + pjp); //执行目标方法 ProceedingJoinPoint表示 doFirst
Object proceed = pjp.proceed(); // method.invoke(),表示执行doFirst()方法本身
//return "HelloAround,不是目标方法的执行结果";
//返回目标方法执行结果,没有修改的
return proceed;
}
}
  • 如果你细心的去将所有通知一起加入进来,那么你会发现其实并不是@After 通知在最后一个执行,这应该是官方经过了很多的测试选择的最佳方案吧。

3.6 Pointcut

  • 这个就是将我们的切入点表达式起一个别名。

四、Spring继承MyBatis

4.1 xml的配置

  • 首先我们需要在mapper.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 读取属性文件jdbc.properties -->
<context:property-placeholder location="jdbc.properties"/>
<!-- 创建数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 配置SqlSessionFactoryBean类 -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 配置数据源-->
<property name="dataSource" ref="dataSource"/>
<!-- 配置MyBatis核心配置文件-->
<property name="configLocation" value="SqlMapConfig.xml"/>
<!-- 注册实体类的别名-->
<property name="typeAliasesPackage" value="com.meteor.pojo"/>
</bean>
<!-- 注册mapper.xml文件-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.meteor.mapper"/>
</bean>
</beans>
  • 配置事务处理
使用 @Transactional(propagation=)
<!-- 事务处理 -->
<!-- 1.添加事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 因为事务必须关联数据库处理,所以要配置数据源 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 添加事务的注解驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
  • JDBC:Connection conn.commit(); conn.rollback();

  • MyBatis:SqlSession sqlSession.commit(); sqlSession.rollback();

  • Hibernate:Session session.commit(); session.rollback();

  • 事务管理器用来生成相应技术的连接 + 执行语句的对象

  • 如果使用MyBatis框架,必须使用DataSourceTransactionManager类完成处理

  • MySQL:mysql默认的事务处理级别是'REPEATABLE-READ',也就是可重复读

4.2 Spring事务传播特性

  • 多个事务之间的合并、互斥等都可以通过设置事务的传播特性来解决

  • PROPAGATION_REQUIRED:必被包含事务(增删改必用)

  • PROPAGATION_REQUIRED_NEW:自己新开事务,不管之前是否有事务

  • PROPAGATION_SUPPORTS:支持事务,如果加入的方法有事务,则支持事务,如果没有,不单开事务

  • PROPAGATION_NEVER:不能运行中事务中,如果包在事务中,抛异常

  • PROPAGATION_NOT_SUPPORTED:不支持事务,运行在非事务的环境

  • 项目中的所有事务,必须添加到业务逻辑层上。

五、结尾

  • 这些只是Spring的基础入门知识,毕竟笔者也仅仅二刷,待笔者闭关修炼,后续会继续更新源码底层知识。
  • 对于Spring内容就总结这么多,若想深入学习等待后续更新。
  • 我将会继续更新关于Java方向的学习知识,感兴趣的小伙伴可以关注一下。
  • 文章写得比较走心,用了很长时间,绝对不是copy过来的!
  • 尊重每一位学习知识的人,同时也尊重每一位分享知识的人。
  • 你的点赞与关注,是我努力前行的无限动力。

Spring基础入门的更多相关文章

  1. Spring基础入门(一)

    一.Spring概念 1.什么是Spring   Spring是一个开源框架,它由Rod Johnson创建.它是为了解决企业应用开发的复杂性而创建的.Spring使用基本的JavaBean来完成以前 ...

  2. Spring 基础入门(一)

    本文代码部分来自于<spring in action>,本文讲的是使用!! Spring 是为了解决什么 一个框架的存在是为了解决某个问题的,那么Spring这个框架是为了解决什么问题呢? ...

  3. Spring基础入门(二)

    一.AOP 1.AOP概念 aop:面向切面编程,扩展功能不修改源代码实现. AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码. 2.AOP原理 (1)第一种情况,有接口情况,使用动态代理创建 ...

  4. Spring基础入门(三)

    一.Spring的jdbcTemplate操作 (1)Spring是一站式框架,对于javaee三层,每一层都有解决技术. web层:springMVC service:spring的ioc dao层 ...

  5. [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.

    前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...

  6. [Spring框架]Spring AOP基础入门总结一.

    前言:前面已经有两篇文章讲了Spring IOC/DI 以及 使用xml和注解两种方法开发的案例, 下面就来梳理一下Spring的另一核心AOP. 一, 什么是AOP 在软件业,AOP为Aspect ...

  7. Spring Boot 入门之基础篇(一)

    原文地址:Spring Boot 入门之基础篇(一) 博客地址:http://www.extlight.com 一.前言 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是 ...

  8. Java基础-SSM之Spring MVC入门篇

    Java基础-SSM之Spring MVC入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spring MVC简介 1>.什么是Spring MVC 答:Sprin ...

  9. Java基础-SSM之Spring快速入门篇

    Java基础-SSM之Spring快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.    Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java ...

随机推荐

  1. SpringJDBC和事务控制

    SpringJDBC和事务控制 主要内容 1.基本配置 <!--依赖导入--> <dependencies> <!-- 添加相关的依赖坐标 --> <!-- ...

  2. SHCTF web题

    第一题:直接查看robots.txt,得到flag 第二题:他的题的意思通过get方式一个字符一个字符去猜如果对的话他下面的小方格就会亮起,用python写个脚本就过了 第三题:也是猜flag 解题方 ...

  3. java高级用法之:JNA中的Structure

    目录 简介 native中的struct Structure 特殊类型的Structure 结构体数组作为参数 结构体数组作为返回值 结构体中的结构体 结构体中的数组 结构体中的可变字段 结构体中的只 ...

  4. Dapr学习(2)之Rancher2.63(k8s&k3s)环境安装Dapr

    前言:前面写过一篇关于dapr入门安装的文章,self-host模式,使用docker安装的本地调试环境,并进行了测试:本篇介绍k8s方式安装dapr,此文主要基于的环境是k3s,通过rancher2 ...

  5. 项目实战:Qt+OpenCV大家来找茬(Qt抓图,穿透应用,识别左右图区别,框选区别,微调位置)

    前言   本项目的出现理由只是笔者的一个念头,于是利用专业Qt和Opencv相关的知识开发一个辅助工具,本文章仅用于Qt和Opencv结合的学习.   Demo演示效果          运行包下载地 ...

  6. 189. Rotate Array - LeetCode

    Question 189. Rotate Array Solution 题目大意:数组中最后一个元素移到第一个,称动k次 思路:用笨方法,再复制一个数组 Java实现: public void rot ...

  7. map计算

    map理解 参考1: https://github.com/rafaelpadilla/Object-Detection-Metrics 参考2:https://github.com/rafaelpa ...

  8. MySQL之事务和redo日志

    事务 事务的四个ACID特性. Atomicity 原子性 Consistency 一致性 Isolation 隔离性 Durability 持久性 原子性 原子性即这个事务的任务要么全做了,要么全部 ...

  9. Go微服务框架go-kratos实战02:proto 代码生成和编码实现步骤

    在上一篇 kratos quickstart 文章中,我们直接用 kratos new 命令生成了一个项目. 这一篇来看看 kratos API 的定义和使用. 一.kratos 中 API 简介 1 ...

  10. MySQL 8.0 Undo Tablespace管理

    目录 1. UNDO 基础概念 2. UNDO 相关参数 2.1 参数含义 3. UNDO 表空间运维 3.1 查看UNDO的基本信息 3.2 添加/active/inactive/删除UNDO表空间 ...