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

【狂神说Java】Spring5

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

【狂神说Java】Spring5

Github代码
【狂神说JAVA】Spring5笔记(所有代码均经过测试)

11、使用Spring实现Aop

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

通知类型连接点实现接口
前置通知方法前org.springframework.aop.MethodBeforeAdvice
后置通知方法后org.springframework.aop.AfterReturningAdvice
环绕通知方法前后org.aopalliance.intercept.MethodInterceptor
异常抛出通知方法抛出异常org.springframework.aop.ThrowsAdvice
引介通知类中增加新的方法属性org.springframework.aop.IntroductionInterceptor

即 Aop 在 不改变原有代码的情况下 , 去增加新的功能 .

11.3 使用Spring实现Aop

【重点】使用AOP织入,需要导入一个依赖包!

   
    org.aspectj
    aspectjweaver
    1.9.4

11.3.1 方式一:使用Spring的API接口

【主要SpringAPI接口实现】

首先编写我们的业务接口和实现类

package com.kuang.service;

public interface UserService {

    public String add();

    public void delete();

    public void update();

    public void select();

}
package com.kuang.service;

public class UserServiceImpl implements UserService{

    @Override
    public String add() {
        System.out.println("增加用户");
        return "sss";
    }

    @Override
    public void delete() {
        System.out.println("删除用户");
    }

    @Override
    public void update() {
        System.out.println("更新用户");
    }

    @Override
    public void select() {
        System.out.println("查询用户");
    }
}
  1. 写我们的增强类 , 我们编写两个 , 一个前置增强 一个后置增强
package com.kuang.log;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class log implements MethodBeforeAdvice {

    //method : 要执行的目标对象的方法
    //objects : 被调用的方法的参数
    //Object : 目标对象
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println( o.getClass().getName() + "的" + method.getName() + "方法被执行了");
    }
}
package com.kuang.log;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class AfterLog implements AfterReturningAdvice {
    //returnValue 返回值
    //method被调用的方法
    //args 被调用的方法的对象的参数
    //target 被调用的目标对象
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行了" + target.getClass().getName()
                +"的"+method.getName()+"方法,"
                +"返回值:"+returnValue);
    }
}


  1. 在spring的文件中注册 , 并实现aop切入实现 , 注意导入约束 .


    
    
    
    

    
    
        
        
        
        
        
    

  1. 测试
package com.kuang.service;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
}
com.kuang.service.MyTest,test
com.kuang.service.UserServiceImpl的add方法被执行了
增加用户
执行了com.kuang.service.UserServiceImpl的add方法,返回值:sss

进程已结束,退出代码为 0

Aop的重要性 : 很重要 . 一定要理解其中的思路 , 主要是思想的理解这一块 .

**Spring的Aop就是将公共的业务 (日志 , 安全等) 和领域业务结合起来 , 当执行领域业务时 , 将会把公共业务加进来 . 实现公共业务的重复利用 . 领域业务更纯粹 , 程序猿专注领域业务 , 其本质还是动态代理 . **

11.3.2 方式二:自定义来实现【主要是切面定义】

目标业务类不变依旧是userServiceImpl

  1. 写我们自己的一个切入类
package com.kuang.diy;

public class DiyPointCut {
    public void before() {
        System.out.println("==========方法执行前============");
    }

    public void after() {
        System.out.println("==========方法执行后============");
    }
}

  1. 去spring中配置



    
    
    

    
    

    
    
        
        
            
            
            
            
            
        
    

	@Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
==========方法执行前============
增加用户
==========方法执行后============

进程已结束,退出代码为 0
11.3.3 方式三:使用注解实现!
  1. 编写一个注解实现的增强类
package com.kuang.diy;

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

//方式三:使用注解的方式实现AOP
@Aspect//标注这个类是一个切面
public class AnnotationPointCut {
    @Before("execution(* com.kuang.service.UserServiceImpl.*(..))")
    public void before() {
        System.out.println("==========方法执行前============");
    }

    @After("execution(* com.kuang.service.UserServiceImpl.*(..))")
    public void after() {
        System.out.println("==========方法执行后============");
    }

    //在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点
    @Around("execution(* com.kuang.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("==========环绕前============");

        //获取签名
        //Signature signature = jp.getSignature();
        //System.out.println("signature:" + signature);

        //执行方法
        Object proceed = jp.proceed();

        System.out.println("==========环绕后============");
    }
}


  1. 在Spring配置文件中,注册bean,并增加支持注解的配置


    
    
    
    
    
    
    

  1. 测试
 	@Test
    public void test3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans3.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
==========环绕前============
==========方法执行前============
增加用户
==========方法执行后============
==========环绕后============

进程已结束,退出代码为 0
12、整合Mybatis 12.1 导入相关jar包
  1. junit

   junit
   junit
   4.12

  1. mybatis

    org.mybatis
    mybatis
    3.5.4


  1. mysql数据库:mysql-connector-java

    mysql
    mysql-connector-java
    8.0.22


  1. spring相关的:spring-webmvc

   org.springframework
   spring-webmvc
   5.1.10.RELEASE


   org.springframework
   spring-jdbc
   5.1.10.RELEASE


  1. aspectJ AOP 织入器

   org.aspectj
   aspectjweaver
   1.9.4


  1. mybatis-spring整合包【重点】

   org.mybatis
   mybatis-spring
   2.0.2


  1. 配置Maven静态资源过滤问题!【约定大于配置】

    
        
            src/main/resources
            
                ***.xml
            
            true
        
        
            src/main/java
            
                ***.xml
            
            true
        
    


12.2 编写mybatis项目

12.3 Mybatis-Spring

Mybatis-Spring官网

  • 什么是 MyBatis-Spring?
    MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。

如果使用 Maven 作为构建工具,仅需要在 pom.xml 中加入以下代码即可:


   org.mybatis
   mybatis-spring
   2.0.2

12.3.1 整合方式一
  1. 引入配置文件



  1. 编写数据源配置

       
       
       
       

  1. 配置sqlSessionFactory

    
    
    
    


  1. sqlSessionTemplate

    
    

  1. 需要给接口加实现类【新加的】
package com.kuang.mapper;

import com.kuang.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class TestDao {
    @Test
    public void getUserList() {
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        UserMapper userDao = context.getBean("userMapper",UserMapper.class);
        List allUser = userDao.getUserList();
        for (User user : allUser) {
            System.out.println(user);
        }
    }
}
  1. 将自己写的实现类,注入到Spring中

    

  1. 测试使用即可
package com.kuang.mapper;

import com.kuang.pojo.User;
import com.kuang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class TestDao {
    @Test
    public void getUserList2() {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
        UserMapper userDao = (UserMapper) context.getBean("userDao");
        List allUser = userDao.getUserList();
        for (User user : allUser) {
            System.out.println(user);
        }
    }
}
User(id=1, name=张三, pwd=123)
User(id=2, name=张三, pwd=123)
User(id=3, name=王五, pwd=789)
User(id=4, name=哈哈, pwd=454)
User(id=7, name=热热热, pwd=7787)
User(id=5, name=王发的, pwd=457)
User(id=8, name=张强, pwd=5754)
User(id=9, name=大款, pwd=4574)
User(id=10, name=张强, pwd=5754)
  • 为了给mybatis-config.xml留点面子(使用方便),在其中将别名和设置留下来




    
        
    


12.3.2 整合方式二(推荐)
  1. 将我们上面写的UserDaoImpl修改一下
package com.kuang.mapper;

import com.kuang.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class UserDaoImpl2 extends SqlSessionDaoSupport implements UserMapper {
    @Override
    public List getUserList() {
        UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
        List allUser = mapper.getUserList();
        return allUser;
    }
}
  1. 修改bean的配置

    

  1. 测试
@Test
public void getUserList2() {
    ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    UserMapper userDao = context.getBean("userMapper2",UserMapper.class);
    List allUser = userDao.getUserList();
    for (User user : allUser) {
        System.out.println(user);
    }
}

总结 : 整合到spring以后可以完全不要mybatis的配置文件,除了这些方式可以实现整合之外,我们还可以使用注解来实现,这个等我们后面学习SpringBoot的时候还会测试整合!

13、声明式事务 13.1 回顾事务
  • 把一组业务当成一个业务来做;要么都成功,要么都失败!
  • 事务在项目开发中,十分重要,涉及到数据的一致性问题,不能马虎
  • 确保完整性和一致性

事务的ACID原则:

  • 原子性(atomicity)
    事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用
  • 一致性(consistency)
    一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中
  • 隔离性(isolation)
    多个业务可能操作同一个资源,防止数据损坏
  • 持久性(durability)
    事务一旦提交,无论系统发生什么问题,结果都不会再被影响,被持久化的写到存储器中!
13.2 案例

新建用户再删除

public int addUser(User user);
public int deleteUserById(int id);
  • 正确的addUser,错误的deleteUserById

   insert user (name, pwd) value (#{name}, #{pwd});



    deletes user where id = #{id}

  • UserDaoImpl
package com.kuang.mapper;

import com.kuang.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper {
    @Override
    public List getUserList() {
        UserMapper mapper = getSqlSession().getMapper(UserMapper.class);

        User user = new User(0,"小王","7458");
        int id = mapper.addUser(user);
        mapper.deleteUserById(id);

         List allUser = mapper.getUserList();
        return allUser;
    }

    public int addUser(User user){
        return getSqlSession().getMapper(UserMapper.class).addUser(user);
    }

    public int deleteUserById(int id){
        return getSqlSession().getMapper(UserMapper.class).deleteUserById(id);
    }
}
  • 测试
@Test
public void getUserList() {
    ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    UserMapper userDao = context.getBean("userMapper",UserMapper.class);
    List allUser = userDao.getUserList();
    for (User user : allUser) {
        System.out.println(user);
    }
}
  • 中断但插入成功,却未删除,不符事务
13.3 Spring中的事务管理
  • 声明式事务:AOP(推荐)

    • 一般情况下比编程式事务好用。
    • 将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。
    • 将事务管理作为横切关注点,通过aop方法模块化。Spring中通过Spring AOP框架支持声明式事务管理
  • 编程式事务:需要在代码中,进行事务的管理

    • 将事务管理代码嵌到业务方法中来控制事务的提交和回滚
    • 缺点:必须在每个事务操作业务逻辑中包含额外的事务管理代码
  • 使用Spring管理事务,注意头文件的约束导入 :tx(事务)

xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

  • 事务管理器

    • 无论使用Spring的哪种事务管理策略(编程式或者声明式)事务管理器都是必须的。
    • 就是 Spring的核心事务管理抽象,管理封装了一组独立于技术的方法。
  • JDBC事务


    

  • 配置事务的通知

    
        
        
        
        
        
        
        
    


  • 配置事务的切入

        
        
    
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/643498.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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