栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring详解

Spring解决企业应用开发的复杂性 histroy

创始人:Rod Johnson

spring理念使现有技术更加容易使用,像是一个粘合剂

SSM: Spring+SpringMVC+MyBatis

官网: Spring | Home 中文网: Spring 中文网 (springref.com)

官方下载地址: https://repo.spring.io/ui/native/libs-release-local/org/springframework/spring/

GitHub上的Spring项目: https://github.com/spring-projects/spring-framework

官方API:https://spring.io/projects/spring-framework#learn
官方文档阅读**:https://docs.spring.io/spring-framework/docs/current/reference/html proxy.add(); } }

如果我们改变了其中的target,就是修改了接口,而这个接口一般是一类业务的方法总和.

所以我们修改其中的target,就是修改了一类业务

同时,因为最后其实调用的invoke方法,我们就可以在这个方法执行的前后,增加操作了,这就是方法增强

这是Spring AOP(面向切面编程)的原理


AOP面向切面编程

实际作用就是:不改变原有代码的情况下,对原有代码进行增强

通过预编译方式,和运行期动态代理,实现程序功能的 统一维护

提供声明式事务,允许用户自定义切面

AOP织入依赖

org.aspectj.aspectjweaver1.9.4

  org.aspectj
  aspectjweaver
  1.9.8.RC1

实现方式 Spring的原生api接口实现

UserService实现了接口User

public interface User {

  void add();
  void delete();
  void query();

}
package com.changGe.li.pojo;

import com.changGe.li.pojo.User;

public class UserImpl implements User{

  @Override
  public void add() {
    System.out.println("add实现了");
  }

  @Override
  public void delete() {
    System.out.println("delete实现了");
  }

  @Override
  public void query() {
    System.out.println("query实现了");
  }

}

自定义类实现方法增强的接口,如MethodBeforeAdvice(切入点之前),AfterRetruningActive(切入点返回值后)

package com.changGe.li.pojo;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

//建议之前的方法:切入点之前的方法
public class LogBefore implements MethodBeforeAdvice {

  @Override
  public void before(Method method, Object[] args, Object target) throws Throwable {
    System.out.println("切入点之前的方法");
  }

  public void beforeTest(){
    System.out.println("切入点之前的方法的测试方法");
  }

}
package com.changGe.li.pojo;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

//afterReturningAdvice返回值后的建议:切入点返回值之后的方法
public class LogAfter implements AfterReturningAdvice {
  @Override
  public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
    System.out.println("切入点返回值之后的方法");
  }

  public void beforeTest(){
    System.out.println("切入点返回值之后的方法的测试方法");
  }

}

beans.xml中导入aop依赖:可以直接


xmlns:aop="http://www.springframework.org/schema/aop"


http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd

配置包扫描




配置bean和aop织入







  
  

  
  
  


测试的时候,spring动态代理的接口,所以application.getBean时,传参与返回值必须是接口类型的

ApplicationContext application = new ClassPathXmlApplicationContext("beans.xml");

User user = application.getBean("userService",User.class);
user.add();

aop切面定义

自定义切面类

package com.changGe.li.pojo;

public class Diy {

  public void before(){
    System.out.println("这是before方法");
  }

  public void after(){
    System.out.println("这是after方法");
  }

}

引用切面类的增强方法






  
  
    

    
    
    
  


User user = application.getBean("userService",User.class);
user.add();
//运行结果
这是before方法
add实现了
这是after方法

注解aop
package com.changGe.li.pojo;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class Diy {

  @Before("execution(* com.changGe.li.pojo.User.*(..))")
  public void before(){
    System.out.println("这是before方法");
  }

  @After("execution(* com.changGe.li.pojo.User.*(..))")
  public void after(){
    System.out.println("这是after方法");
  }

  @After("execution(* com.changGe.li.pojo.User.*(..))")
  public void after1(){
    System.out.println("这是after方法1");
  }

  //环绕增强:代理对象执行方法的时候,把所有的增强方法都执行了一遍
  @Around("execution(* com.changGe.li.pojo.User.*(..))")
  //point代表获取被切入的点
  public void around(ProceedingJoinPoint point){
    System.out.println("环绕前");

    //获取签名,也就是方法名()
    Signature signature = point.getSignature();
    System.out.println("签名是:"+signature);

    Object proceed = null;
    try {
      //执行方法
      proceed = point.proceed();
    } catch (Throwable e) {
      e.printStackTrace();
    }

    System.out.println("环绕后");
    System.out.println("返回值是:"+proceed);
  }

}

开启注解增强,就不用配置其他的aop织入了



//运行结果:可以看出:
//就是在代理对象执行方法的时候,把所有的增强方法都执行了一遍
环绕前
签名是:void com.changGe.li.pojo.User.add()
这是before方法
add实现了
这是after方法1
这是after方法
环绕后
返回值是:null

整合MyBatis

Access denied for user ‘’@‘localhost’ (using password: YES)错误解决方法

(7条消息) MySQL Access denied for user ‘root‘@‘localhost‘ (using password: YES/NO) 的原因以及解决方案_花花花菜的博客-CSDN博客

加上mybatis-spring和spring-jdbc的依赖

基本的mybatis和mysql的依赖,可能会用到的都可以导入一遍



  org.mybatis
  mybatis-spring
  2.0.6



  org.springframework
  spring-jdbc
  5.3.13




  mysql
  mysql-connector-java
  8.0.27




  org.mybatis
  mybatis
  3.5.7

package com.changGe.li.pojo;

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class Student {
  private String id;
  private String name;
  private int tid;
}
package com.changGe.li.pojo;

import java.util.List;

public interface StudentMapper {

  List getStudentList();

}

jdbc.properties

driver=com.mysql.cj.jdbc.Driver
username=root
password=root
url=jdbc:mysql:///mybatis?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC

mybatis-config.xml




    
    
        
    
    
    
        
    


StudentMapper.xml





    

测试

StudentMapper studentMapper = applicationContext.getBean("studentMapperImpl", StudentMapper.class);

Student student = new Student("14","路飞",1);
studentMapper.insertStudent(student);

studentMapper.deleteStudentById("1");

最后insert还是被执行了


这时我们就需要配置事务是为了:保证ACID原则



  

导入aop和tx约束




  
    
    

    
    

    
    
  






  
  
  
  

spring事务传播属性

Spring事务的传播:PROPAGATION_REQUIRED - 神只吃苹果 - 博客园 (cnblogs.com)

在 spring的 TransactionDefinition接口中一共定义了六种事务传播属性:

PROPAGATION_REQUIRED – 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS – 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY – 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW – 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED – 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER – 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED – 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)


事务的隔离级别

(7条消息) spring 中 isolation 和 propagation 详解_饥饿小猪的博客-CSDN博客

  1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应
  2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
  3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
  4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/827142.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号