• 【SSM框架 二】Spring


    二、Spring

    1、简介

    Spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架

    • 2002年,首次推出Spring框架的雏形,interface21框架

    • 2004年3月24日,Spring框架以interface21为基础,经过重新设计发布了1.0正式版

    • 开源的免费框架

    • 轻量级非入侵式框架

    • 支持对事务的处理,对框架整合的支持

    • 官方网站:https://spring.io/

    • 5.2.23官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/

    • api文档:https://docs.spring.io/spring-framework/docs/current/javadoc-api/

    • 老版本文档:https://docs.spring.io/spring-framework/docs/5.0.10.RELEASE/spring-framework-reference/(更改地址中间的版本号访问响应版本)

    • 老版本jar包下载地址:https://repo.spring.io/ui/native/release/org/springframework/spring

    • github下载地址:https://github.com/spring-projects/spring-framework

    • maven仓库

      • 
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>5.3.23version>
        dependency>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
      • 
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>5.3.23version>
        dependency>			
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7

    2、IOC理论思想

    IOC全称是Inversion of Control,控制反转

    它是一种设计思想,由容器将设计好的对象交给容器控制,而非对象内部直接new

    传统的Java设计中,直接会在对象的内部通过new进行对象的创建,是程序主动创建以来对象;

    对Ioc来说,有一个专门的容器专门管理这些对象的生命周期,控制对象的创建;所以在Ioc中,是通过Ioc容器控制对象,由Ioc容器控制外部资源的获取

    3、Hello Spring

    bean.xml

    
    
    
    
    
        
    
    
    
    
            
            
        
        
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    测试类

    import com.daban.pojo.Hello;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Mytest {
        public static void main(String[] args) {
            // 获取spring的上下文对象
            // 参数可以有多个xml文件
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
            // 由上下文对象得到bean对象
            // 第一个参数为对象的名字(对应xml的bean标签中的id值)
            // 第二个参数为该bean对象的类型,避免了强制类型转换
            Hello hello = applicationContext.getBean("hello1", Hello.class);
            System.out.println(hello.toString());
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4、IOC创建对象的方式

    4.1 无参构造构造器注入

    ​ 默认使用无参构造器

    4.2 有参构造器注入

    三种方式,只能使用其中之一

    • 变量索引+值的方式

      • <constructor-arg index="0" value="野山鸡">
        
        • 1
    • 类型+值的方式,如果两个String就不太好分辨,不推荐

      • <constructor-arg type="java.lang.String" value="野山鸡"/>
        
        • 1
    • 变量名+值的方式

      • <constructor-arg name="name" value="野山鸡"/>
        
        • 1

    总结:在配置文件被加载的时候,容器中管理的对象就已经被初始化了

    5、Spring的配置

    5.1 别名

    给bean的id取一个别名。设置别名后,使用别名和原先的名字都可以

    <alias name="user" alias="user2"/>
    
    • 1

    5.2 Bean的配置

    属性作用备注
    idbean的唯一标识,类似与对象名
    classbean所对应的类全限名
    name取别名,可以取多个,和alisa标签类似

    5.3 import

    一般用于团队开发使用,把其他多个配置文件合并到一个配置文件中,加载配置文件时,只加载一个就行

    <import resource="bean2.xml"/>
    
    • 1

    6、DI依赖注入

    6.1 构造方法注入

    详看《IOC创建对象的方式》

    6.2 set方法注入

    
    <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="student" class="com.daban.pojo.Student">
            
            <property name="name" value="青山"/>
            
            <property name="address" ref="address"/>
            
            <property name="book">
               <array>
                   <value>西游记value>
                   <value>三国演义value>
                   <value>红楼梦value>
                   <value>水浒传value>
               array>
            property>
            
            <property name="hobbys">
                <list>
                    <value>唱歌value>
                    <value>弹吉他value>
                    <value>骑行value>
                list>
            property>
            
            <property name="card">
                <map>
                    <entry key="身份证" value="12345512351512553"/>
                    <entry key="银行卡" value="662522512525221"/>
                map>
            property>
            
            <property name="games">
                <set>
                    <value>吃鸡value>
                    <value>LOLvalue>
                set>
            property>
            
            <property name="info">
                <props>
                    <prop key="username">张三prop>
                    <prop key="password">112233prop>
                props>
            property>
            
            <property name="wife">
                <null/>
            property>
    
        bean>
        <bean id="address" class="com.daban.pojo.Address">
            <property name="address" value="陕西西安"/>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    6.3 扩展注入

    • p命名空间注入(和set方法注入作用一样)

      • 需要加入p的命名空间
        xmlns:p=“http://www.springframework.org/schema/p”

      • <bean id="user" class="com.daban.pojo.User" p:age="12" p:name="雪山"/>
        
        • 1
    • c命名空间注入(和构造器方法注入作用一样)

      • 需要加入c的命名空间
        xmlns:c=“http://www.springframework.org/schema/c”

      • <bean id="user" class="com.daban.pojo.User" c:age="12" c:name="青山"/>
        <bean id="user" class="com.daban.pojo.User"  c:_0="青山" c:_1="13" />
        
        • 1
        • 2

    6.4、Bean的作用域

    bean标签的属性中设置scope

    作用域描述备注
    singleton单例模式每次从容器中get,就会的到同一个对象
    prototype原型模式每次从容器中get,就会的到一个新对象
    request再一次请求中
    session再一次会话中
    application在一个应用中

    7、Bean的自动装配

    Spring中装配的三种方式

    • 在xml中显式的配置
    • 在java中显式的配置
    • 隐式的自动装配

    7.1 正常装配

    <bean id="person" class="com.daban.pojo.Person">
        <property name="name" value="川崎"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    bean>
    <bean id="cat" class="com.daban.pojo.Cat"/>
    <bean id="dog" class="com.daban.pojo.Dog"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    7.2 自动装配

    
        <bean id="person" class="com.daban.pojo.Person" autowire="byName">
            <property name="name" value="川崎"/>
        bean>
        <bean id="cat" class="com.daban.pojo.Cat"/>
        <bean id="dog" class="com.daban.pojo.Dog"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    7.3 使用注解自动装配

    7.3.1 要使用注解的准备
    • 导入需要的约束context

      • xm<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
               http://www.springframework.org/schema/context/spring-context.xsd">
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
    • 配置注解支持,加入如下,开能开启注解

      • <context:annotation-config/>
        
        • 1
    7.3.2 注解解释
    注解解释备注
    @Autowired直接使用在需要装配的属性上使用后可以省去set方法
    @Qualifier(value = “xxx”)匹配id为value值的bean自动装配环境复杂bean不唯一时使用
    @Resourcejava的自动装配先用名字查询,查不到使用类型
    @Nullable该字段可以为null

    8、使用注解开发

    使用注解必须保证aop包的导入

    必须导入约束context

    
    <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
           http://www.springframework.org/schema/context/spring-context.xsd">
    
    
        <context:annotation-config/>
    
        <context:component-scan base-package="com.daban.pojo"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    注解描述备注
    @Component放在类上,说明被spring管理,将该类放在容器中就是bean
    @Value(“XXX”)属性注入,属性上复杂的属性建议使用配置文件
    @Repository和@Component一样,只是在dao层使用这个
    @Service和@Component一样,只是在Service层使用这个
    @Controller和@Component一样,只是在Controller层使用这个
    @Scope(“xxx”)bean的作用域

    9、使用java的方式配置spring

    实体类

    package com.daban.pojo;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    //@Component注册一个组件,在这里可以省略
    @Component
    public class User {
        @Value("hhhhh")
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    配置类

    package com.daban.config;
    
    import com.daban.pojo.User;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    //@Configuration代表这是一个配置类,可省略
    //@Bean相当于注册一个bean,id就是方法名,class就是方法返回值
    @Configuration
    public class MyConfig {
        @Bean
        public User getUser(){
            return new User();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    测试类

    import com.daban.config.MyConfig;
    import com.daban.pojo.User;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
            User user = context.getBean("getUser", User.class);
            System.out.println(user.toString());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    10、代理模式

    SpringAOP的底层就使用代理模式

    10.1 静态代理

    角色分析:

    • 抽象角色:一般会使用接口或抽象类来实现
    • 真是角色:被代理的对象
    • 代理角色:去代理正式角色,代理的过程中,会做一些附属操作
    • 客户:访问代理对象的人

    静态代理模式的优点:

    • 可以是真是角色操作更加纯粹,不用关心一些公共业务
    • 公共业务交给代理角色,实现了业务的分工
    • 公共业务发生扩展时,方便集中管理

    静态代理模式的缺点:

    • 一个真实角色就要产生一个代理角色,代码量会翻倍,开发效率变低(使用动态代理解决)

    代码步骤:

    1、接口

    package com.daban.demo01;
    
    public interface Rent {
        public void rent();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、真实角色

    package com.daban.demo01;
    
    public class Host implements Rent {
    
        private int NO;
    
        public Host() {
        }
    
        public Host(int NO) {
            this.NO = NO;
        }
    
        @Override
        public void rent() {
            System.out.println(NO+"号房东要出租房子");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3、代理角色

    package com.daban.demo01;
    
    public class Proxy implements Rent{
        private Host host;
    
        public Proxy() {
        }
    
        public Proxy(Host host) {
            this.host = host;
        }
    
        @Override
        public void rent() {
            seeHouse();
            fare();
            host.rent();
        }
        public void seeHouse(){
            System.out.println("中介带你看房");
        }
        public void fare(){
            System.out.println("收取中介费");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4、客户端访问代理角色

    package com.daban.demo01;
    
    public class Client {
        public static void main(String[] args) {
            Proxy proxy = new Proxy(new Host(2));
            proxy.rent();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    10.2 动态代理

    • 动态代理和静态代理角色一样
    • 动态代理类是动态生成的,不是我们创建的
    • 动态代理分为两大类:
      • 基于接口的动态代理:JDK动态代理【这里使用这个】
      • 基于类的动态代理:cglib

    基本示例:

    接口:

    package com.daban.demo02;
    
    public interface Rent {
        public void rent();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    实现类:

    package com.daban.demo02;
    
    
    public class Host implements Rent  {
    
        private int NO;
    
        public Host() {
        }
        public Host(int NO) {
            this.NO = NO;
        }
    
        @Override
        public void rent() {
            System.out.println(NO+"号房东要出租房子");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    动态生成类:

    package com.daban.demo02;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    //使用这个类自动生成代理类
    public class ProxyInvocationHandler implements InvocationHandler {
    
        //被代理的接口
        private Rent rent;
        public void setRent(Rent rent) {
            this.rent = rent;
        }
    
        //生成得到的代理类
        public Object getProxy(){
           return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);
        }
        //处理代理实例,并返回结果
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            seeHouse();
            Object result = method.invoke(rent, args);
            fare();
            return result;
        }
        public void seeHouse(){
            System.out.println("中介带你看房");
        }
        public void fare(){
            System.out.println("收取中介费");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    测试类:

    package com.daban.demo02;
    
    public class Client {
        public static void main(String[] args) {
            //真实角色
            Host host = new Host(3);
            //用这个来生成代理类
            ProxyInvocationHandler handler = new ProxyInvocationHandler();
    
            handler.setRent(host);
            //生成代理类
            Rent proxy =(Rent)handler.getProxy();
            proxy.rent();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    通用示例:

    接口:

    package com.daban.demo03;
    
    public interface UserService {
        void add();
        void delete();
        void update();
        void select();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    实现类

    package com.daban.demo03;
    
    public class UserServiceImp implements UserService{
        @Override
        public void add() {
            System.out.println("增加用户");
        }
    
        @Override
        public void delete() {
            System.out.println("删除用户");
        }
    
        @Override
        public void update() {
            System.out.println("修改用户");
        }
    
        @Override
        public void select() {
            System.out.println("查询用户");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    动态生成类(通用了):

    package com.daban.demo03;
    
    import com.daban.demo02.Rent;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    //使用这个类自动生成代理类
    public class ProxyInvocationHandler implements InvocationHandler {
    
        //被代理的接口
        private Object target;
        public void setTarget(Object target) {
            this.target = target;
        }
    
        //生成得到的代理类
        public Object getProxy(){
           return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
        }
        //处理代理实例,并返回结果
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            log(method.getName());
            Object result = method.invoke(target, args);
            return result;
        }
        //增加想要的附属功能,不用改变原代码
        public void log(String msg){
            System.out.println("执行了"+msg+"方法");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    测试类:

    package com.daban.demo03;
    
    public class Client {
        public static void main(String[] args) {
            UserServiceImp userServiceImp = new UserServiceImp();
            ProxyInvocationHandler handler = new ProxyInvocationHandler();
            handler.setTarget(userServiceImp);
            UserService proxy = (UserService) handler.getProxy();
            proxy.add();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    11、AOP实现方式

    11.1 什么是AOP

    什么是AOP:面向切面编程

    11.2 Aop在Spring中的作用

    名词:

    • 横切关注点:跨越应用程序多个模块的方法和功能。如日志,安全,缓存,事务
    • 切面(ASPECT):横切关注点被模块化的对象,他是一个类。(例如Log类)
    • 通知(Advice):切面必须要完成的工作,即它类中的一个方法。(例如Log类中的方法)
    • 目标(Target):被通知对象。(接口)
    • 代理(Proxy):向目标对象应用通知之后创建的对象。(生成的代理类)
    • 切入点(PointCut):切面通知执行地点的定义
    • 连接点(JointPoint):与切入点匹配的执行点

    SpringAOP中,通过Advice定义横切逻辑,支持五种类型的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

    11.3.1 使用前需要导入依赖包
    
    <dependency>
        <groupId>org.aspectjgroupId>
        <artifactId>aspectjweaverartifactId>
        <version>1.9.9.1version>
        <scope>runtimescope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    11.3.2 方式一:使用原生的spring api接口
    1. 准备业务接口
    package com.daban.service;
    
    public interface UserService {
        void add();
        void delete();
        void update();
        void select();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 准备业务实现类
    package com.daban.service;
    
    public class UserServiceImp implements UserService{
        @Override
        public void add() {
            System.out.println("增加了一个用户");
        }
        @Override
        public void delete() {
            System.out.println("删除了一个用户");
        }
        @Override
        public void update() {
            System.out.println("改变了一个用户");
        }
        @Override
        public void select() {
            System.out.println("查询了一个用户");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. 准备需要切入的类
    package com.daban.log;
    import org.springframework.aop.MethodBeforeAdvice;
    import java.lang.reflect.Method;
    //需要切入的类需要实现相应的接口,11.2中五种接口都可以,扮演不同的方式
    public class Log implements MethodBeforeAdvice {
        /**
         * method:要执行的目标对象的方法
         * args:参数
         * target:目标对象
         */
        @Override
        public void before(Method method, Object[] args, Object target) throws Throwable {
            System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 准备配置文件
    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd">
    
        
        <bean id="userService" class="com.daban.service.UserServiceImp"/>
        <bean id="log" class="com.daban.log.Log"/>
        <bean id="afterLog" class="com.daban.log.AfterLog"/>
        
        
     	<aop:config>
            
            
            
            <aop:pointcut id="pointcut" expression="execution(* com.daban.service.UserServiceImp.*(..))"/>
            
            
            
            <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
            <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
         aop:config>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    1. 测试类
    import com.daban.service.UserService;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            //动态代理类代理的是接口,所以这里使用UserService接口,而不使用实现类
            UserService userService = context.getBean("userService", UserService.class);
            userService.add();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    11.3.3 方式二:自定义类
    1. 准备业务接口,和方式一相同
    2. 准备业务接口的实现,和方式一相同
    3. 自定义一个类(切面)
    package com.daban.diy;
    
    public class DiyPointcut {
        public void before(){
            System.out.println("********方法执行前********");
        }
        public void after(){
            System.out.println("========方法执行后========");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 准备配置文件
    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd">
    
        
        <bean id="userService" class="com.daban.service.UserServiceImp"/>
        <bean id="log" class="com.daban.log.Log"/>
        <bean id="afterLog" class="com.daban.log.AfterLog"/>
    
        
        <bean id="diy" class="com.daban.diy.DiyPointcut"/>
        <aop:config>
            
            <aop:aspect ref="diy">
                
                <aop:pointcut id="pointcut" expression="execution(* com.daban.service.UserServiceImp.*(..)))"/>
                
                <aop:after method="after" pointcut-ref="pointcut"/>
                <aop:before method="before" pointcut-ref="pointcut"/>
            aop:aspect>
        aop:config>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    1. 测试类,和方式一相同
    11.3.4 方式三:使用注解实现
    1. 准备业务接口,和方式一相同
    2. 准备业务接口的实现,和方式一相同
    3. 自定义一个类(切面)
    package com.daban.diy;
    
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    
    @Aspect//标注这个类是一个切面
    public class AnnotationPointCut {
        //设置切入点在要切入的方法上
        @Before("execution(* com.daban.service.UserServiceImp.*(..)))")
        public void before(){
            System.out.println("********注解方式方法执行前********");
        }
        @After("execution(* com.daban.service.UserServiceImp.*(..)))")
        public void after(){
            System.out.println("========注解方式方法执行后========");
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1. 准备配置文件
    
    <bean id="anntation" class="com.daban.diy.AnnotationPointCut"/>
    
    <aop:aspectj-autoproxy/>
    
    • 1
    • 2
    • 3
    • 4
    1. 测试类,和方式一相同

    12、整合Mybatis

    12.1 回忆mybatis

    步骤:

    1. 导入jar包

    ​ junit,mybatis,mysql数据库,spring相关,aop植入,mybatis-spring

    <dependencies>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.47version>
        dependency>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.5.11version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>5.3.23version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>5.1.9.RELEASEversion>
        dependency>
        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjweaverartifactId>
            <version>1.9.9.1version>
        dependency>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
            <version>2.0.2version>
        dependency>
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    1. 写实体类
    package com.daban.pojo;
    
    import lombok.Data;
    
    @Data
    public class User {
        private int id;
        private String name;
        private String pwd;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 写mybatis核心配置文件
    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <package name="com.daban.pojo"/>
        typeAliases>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                dataSource>
            environment>
        environments>
        <mappers>
            <mapper resource="UserMapper.xml"/>
        mappers>
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    1. 编写接口
    package com.daban.mapper;
    
    import com.daban.pojo.User;
    
    import java.util.List;
    
    public interface UserMapper {
       public List<User> getUser();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 编写接口对应的mapper文件
    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.daban.mapper.UserMapper">
        <select id="getUser" resultType="user">
            select * from mybatis.user
        select>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 测试
    import com.daban.mapper.UserMapper;
    import com.daban.pojo.User;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    public class MyTest {
        @Test
        public void test() throws IOException {
            String resources = "mybatis-config.xml";
            InputStream resource = Resources.getResourceAsStream(resources);
            SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resource);
            SqlSession sqlSession = build.openSession(true);
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> user = mapper.getUser();
            for (User user1 : user) {
                System.out.println(user1);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    12.2 mybatis-spring

    1. 导入jar包
    2. 写实体类
    3. 写mybatis核心配置文件
    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <package name="com.daban.pojo"/>
        typeAliases>
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 编写接口
    package com.daban.mapper;
    
    import com.daban.pojo.User;
    
    import java.util.List;
    
    public interface UserMapper {
       public List<User> getUser();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 编写接口对应的mapper文件
    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.daban.mapper.UserMapper">
        <select id="getUser" resultType="user">
            select * from mybatis.user
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 编写接口的实现类
    package com.daban.mapper;
    
    import com.daban.pojo.User;
    import org.mybatis.spring.SqlSessionTemplate;
    
    import java.util.List;
    
    public class UserMapperImp implements UserMapper{
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        @Override
        public List<User> getUser() {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.getUser();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. 编写spring配置文件
    
    <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="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8"/>
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
         bean>
        
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
            
            <property name="mapperLocations" value="classpath:UserMapper.xml"/>
        bean>
        
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            
            <constructor-arg index="0" ref="sqlSessionFactory"/>
        bean>
        <bean id="userMapper" class="com.daban.mapper.UserMapperImp">
            <property name="sqlSession" ref="sqlSession"/>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    1. 测试
    import com.daban.mapper.UserMapper;
    import com.daban.pojo.User;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.io.IOException;
    import java.util.List;
    
    public class MyTest {
        @Test
        public void test() throws IOException {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
            UserMapper bean = context.getBean("userMapper",UserMapper.class);
            List<User> user = bean.getUser();
            for (User user1 : user) {
                System.out.println(user1);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    12.3 获得SqlSession的方式二

    参见官网http://mybatis.org/spring/zh/sqlsession.html#SqlSessionDaoSupport

    13、声明式事务

    13.1 spring中的事务管理

    • 声明式事务:aop
    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg ref="dataSource"/>
    bean>
    
    
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        
        
        <tx:attributes>
            <tx:method name="add" propagation="REQUIRED"/>
            
            <tx:method name="*" propagation="REQUIRED"/>
        tx:attributes>
    tx:advice>
    
    <aop:config>
        <aop:pointcut id="txPointCut" expression="execution(* com.daban.mapper.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    aop:config>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 编程式事务:需要在代码中进行事务管理(需要改源代码)
  • 相关阅读:
    vue3项目的创建和配置文件
    深信服C++笔试
    kafka学习之三_信创CPU下单节点kafka性能测试验证
    stm32的时钟、中断的配置(针对寄存器),一些基础知识
    Qgis加载arcgis的gdb格式数据
    离线安装docker-compose
    Kruskal重构树 学习笔记
    嵌入式和 Java 走哪条路?
    web前端期末大作业网页设计与制作 ——汉口我的家乡旅游景点 5页HTML+CSS+JavaScript
    卷积神经网络到底是什么,卷积神经网络是一种
  • 原文地址:https://blog.csdn.net/daban2008/article/details/128174993