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

Spring5框架知识总结

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

Spring5框架知识总结

学习--实践--总结--实践--总结........

Spring简介:

(1)核心:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的框架。

(2)特点:

        <1>轻量级的开源的 JavaEE 框架

        <2>方便解耦,简化开发

        <3>方便进行事务操作 

        <4>方便和其他框架进行整合......

(3)组成:

Spring框架其实是一个分层架构,它由多个模块组成,每个模块既可以单独存在,也可以与其他模块联合实现。

Spring-Core(核心容器):提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转将应用程序的配置和依赖性规范与实际的应用程序代码分开。

Spring-Context:这是一个配置文件,向 Spring 框架提供上下文信息。

Spring-Aop:面向切面编程,利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。 

Spring-DAO: 它提供了异常层次结构,利用该结构来管理异常处理和不同数据库供应商抛出的错误消息。这样,我们在编写代码时就无需考虑捕获每种技术不同的异常,降低了需要编写的异常代码数量。

Spring-Web:Web上下文模块建立于应用上下文模块之上,提供了一个适合于Web应用的上下文,对Web开发提供功能上的支持,如请求,表单,异常等。

Spring Web MVC:实现了Spring MVC的Web应用,Spring的MVC框架使用IoC对控制逻辑和业务对象提供了完全的分离。

Spring-ORM:关系映射模块,对流行的对象关系映射 API,包括 JPA、JDO、Hibernate 和 iBatis 提供了的集成层。通过ORM包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,方便开发时小组内整合代码。

spring5入门案例:

1、下载spring5

下载地址 https://repo.spring.io/release/org/springframework/spring/

2、创建一个普通的Javaweb项目

3、在web/WEB-INF/lib下引入jar包(从上述下载的spring中去找)

4、创建User实体类、测试类和xml配置文件:

User实体类:

public class User {
    public void add(){
        System.out.println("add......");
    }
}

testAdd实体类:

public class testAdd {
    @Test
    public void test(){
        //加载spring配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("/bean1.xml");
        //获取配置创建的对象
        User user = context.getBean("user",User.class);
        System.out.println(user);
        user.add();
    }
}

bean1.xml:



    
    

 执行结果:

IOC详解:【重点】 1、什么是IOC:

        IOC不是什么技术,而是一种设计思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。在Java开发中,IOC的设计思想就是将你设计好的对象交给spring容器控制,而不是传统的在类的内部主动创建依赖对象。既然IOC表示控制反转,那么问题来了:

        <1>什么是控制?控制了什么?

        <2>什么是反转?反转之前是谁控制的?反转之后又是谁控制的?如何控制的?

        <3>为什么要反转?反转之前有什么不足?反转之后又能带来什么好处呢?

第一个问题:什么是控制?控制了什么?

        我们在用Spring的时候,通常会创建一些类UserService、CustomerService.....同时我们也知道程序在真正运行的时候用到的是具体的UserService对象、CustomerService对象,那么这些对象
是什么时候创建的?谁创建的?包括对象里的属性是什么时候赋的值?谁赋的?我们在开发过程中只是写了类而已,所有这些都是spring帮我们完成的。这也就是问题的答案控制:

控制对象的创建控制对象内属性的赋值

        当然,如果我们不用Spring,那我们就得自己来做这两件事;反之,我们要做的仅仅是定义类,以及定义哪些属性需要Spring来赋值,由容器来帮忙创建及注入依赖对象(比如某个属性上加@Autowired),这就是反转,表示一种对象控制权的转移。

 那么为什么要反转呢?如果我们自己创建对象,自己给对象中的属性赋值,会出现什么情况?

A类,A类里有一个属性C c;B类,B类里也有一个属性C c;C类

    按照传统的方式,现在程序要运行,那么这三个类的对象都需要创建出来,并且相应的属性都需要有值,那么除了定义这三个类之外,我们还得额外编写创建对象并赋值,如下所示:

A a = new A();B b = new B();C c = new C();a.c = c;b.c = c;

        这五行代码是不用Spring的情况下多出来的代码,如果类在多一些,类中的属性在多一些,那相应的代码会更多、更复杂。反之,将对象交给Spring来控制,极大地减轻了程序员的负担。

        总结:IOC表示控制反转,如果用spring,那么spring会负责来创建对象以及给对象内的属性赋值;也就是说,对象的控制权将会转交给spring。

2、IOC底层原理

        <1>创建XML配置文件,配置创建的对象

        <2>创建一个工厂类:使用dom4j解析配置文件+反射

public class UserFactory{

    public static UserDao getDao(){

        //使用dom4j解析配置文件

        String classValue="class属性值";//xml解析

        Class class=Class.forName(classValue);//通过反射来创建class对象

        return (UserDao)class.newInstatnce();

    }

} 
3、Spring 提供 IOC 容器实现两种方式:(两个接口)

(1)BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用 * 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象

(2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人 员进行使用 --------加载配置文件时候就会把在配置文件内的对象进行创建。

4、IOC操作Bean管理(基于 xml 方式)

(1)基于 xml 方式创建对象

        <1>使用 bean 标签,标签里面添加对应属性,就可以实现对象创建

        <2>常用的属性

                * id 属性:唯一标识;

                * class 属性:类全路径(包类路径);

        <3>在创建对象时候,默认也是执行无参数构造方法完成对象创建

(2)基于 xml 方式注入属性 --------DI(依赖注入)就是注入属性

(3)使用 set 方法进行注入

        <1>创建类,定义属性和对应的 set 方法

//使用 set 方法进行注入属性
public class Book {
     //创建属性
     private String bname;
     private String bauthor;
     //创建属性对应的 set 方法
     public void setBname(String bname) {
         this.bname = bname;
     }
     public void setBauthor(String bauthor) {
         this.bauthor = bauthor;
     }
}

        <2>在 spring 配置文件配置对象创建,配置属性注入


 
 
 

(4)使用有参数构造进行注入

        <1>创建类,定义属性,创建属性对应有参数构造方法

public class Orders {
 //属性
 private String oname;
 private String address;
 //有参数构造
 public Orders(String oname,String address) {
 this.oname = oname;
 this.address = address;
 }
}

        <2>在 spring 配置文件中进行配置


 
 

(5)p 名称空间注入(了解)

        <1>添加 p 名称空间到配置文件中

        <2>进行属性注入,在 bean 标签里面进行操作




5、IOC 操作 Bean 管理(xml 注入其他类型属性)

(1)字面量

        <1>对象的属性值为null


      
                
       

        <2>属性值包含特殊符号


  
       
          >]]>
       
  

(2)注入属性(外部 bean)

        <1>创建两个类: UserService类和 UserDao类

        <2>在 service 调用 dao 里面的方法

public class UserService {
 //创建 UserDao 类型属性,生成 set 方法
 private UserDao userDao;
 public void setUserDao(UserDao userDao) {
 this.userDao = userDao;
 }
 public void add() {
 System.out.println("service add......");
 userDao.update();
 }
}

        <3>在 spring 配置文件中进行配置


    
    

(3)注入属性(内部Bean)

        在实体类之间表示一对多的关系(员工和部门)

        <1>部门类:

public class Dept {
 private String dname;
 public void setDname(String dname) {
 this.dname = dname;
 }
}

        <2>员工类:

//员工类
public class Emp {
    private String ename;
    private String gender;
    //员工属于某一个部门,使用对象形式表示
    private Dept dept;
    public void setDept(Dept dept) {
        this.dept = dept;
    }
    public void setEname(String ename) {
        this.ename = ename;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
}

        <3>在spring配置文件中进行配置

    
    
        
        
        
        
        
            
                
            
        
    

(4)注入属性(级联赋值)

        <1>第一种方式:

    
    
        
        
        
        
        
    
    
        
    

        <2>第二种方式:

------员工属于部门,适用对象形式表示(生成对应的get、set方法)。

    
    
        
        
        
        
        
        
    
    
        
    
6、IOC 操作 Bean 管理(xml 注入集合属性)

        准备工作:创建类,定义数组、list、map、set 类型属性,生成对应 set 方法,并在 spring 配置文件进行配置。

public class Stu {
   //1 数组类型属性
   private String[] courses;
   //2 list 集合类型属性
   private List list;
   //3 map 集合类型属性
   private Map maps;
   //4 set 集合类型属性
   private Set sets;
   public void setSets(Set sets) {
   this.sets = sets;
   }
   public void setCourses(String[] courses) {
   this.courses = courses;
   }
   public void setList(List list) {
   this.list = list;
   }
   public void setMaps(Map maps) {
   this.maps = maps;
   }
}

     注意:map和其他集合注入是有差异的,区分记忆。

    
    
        
        
            
                java 课程
                数据库课程
            
        
        
        
            
                张三
                李四
            
        
        
        
            
                
                
            
        
        
        
            
                MySQL
                Redis
            
        
    

(1)在集合里面设置对象类型值:

public class Course {
    private String cname;   //课程名称

    public void setCname(String cname) {
        this.cname = cname;
    }

    @Override
    public String toString() {
        return "Course{" +
                "cname='" + cname + ''' +
                '}';
    }
}
    
     
        
        
            
                
                
            
        
    
    
    
        
    

    
        
    

(2)把集合注入部分提取出来:

        <1>在spring命名空间中引入util

        <2>使用util 标签完成list集合注入提取

    
    
        易筋经
        九阴真经
        九阳神功
    

        <3>提取 list 集合类型属性注入使用

    
        
    
7、IOC 操作 Bean 管理(FactoryBean)

(1)Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean(FactoryBean)

(2)普通 bean:在配置文件中定义 bean 类型就是返回类型;

(3)工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样

        <1>第一步创建类,让这个类作为工厂 bean,实现接口 FactoryBean;

        <2>第二步实现接口里面的方法,在实现的方法中定义返回的 bean 类型;

public class Course {
    private String cname;

    public void setCname(String cname) {
        this.cname = cname;
    }
    @Override
    public String toString() {
        return "Course{" +
                "cname='" + cname + ''' +
                '}';
    }
}
public class MyBean implements FactoryBean {
    //定义返回 bean
    @Override
    public Course getObject() throws Exception {
        Course course = new Course();
        course.setCname("abc");
        return course;
    }
    @Override
    public Class getObjectType() {
        return null;
    }
    @Override
    public boolean isSingleton() {
        return false;
    }
}
 
     @Test
    public void test3() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean.xml");
        Course course = context.getBean("myBean", Course.class);
        System.out.println(course);
    }
8、Bea的作用域:

在Spring里面,bean 默认是单实例对象。

如何设置单实例还是多实例?

(1)在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例

(2)scope属性值:

        第一个值 默认值,singleton,表示是单实例对象;

        第二个值 prototype,表示是多实例对象;

(3)singleton 和 prototype 区别:

         一、 singleton单实例,prototype 多实例

        二 、设置 scope值是singleton时,加载 spring 配置文件时就会创建单实例对象,设置 scope值是prototype时,不是在加载 spring 配置文件时候创建对象,在调用 getBean 方法时候创建多实例对象;

9、Bean生命周期:

(1)通过无参构造创建 Bean 实例

(2)调用set方法为 Bean 的属性设置值和对其他 bean 引用

(3)调用 Bean 的初始化的方法(配置初始化的方法)

(4)使用Bean(对象获取到了)

(5)当容器关闭时候,调用 Bean的销毁的方法(配置销毁的方法)

public class Orders {
    //无参数构造
    public Orders() {
        System.out.println("第一步 执行无参数构造创建 bean 实例");
    }
    private String oname;
    public void setoname(String oname) {
        this.oname = oname;
        System.out.println("第二步 调用 set 方法设置属性值");
    }
    //创建执行的初始化的方法
    public void initMethod() {
        System.out.println("第三步 执行初始化的方法");
    }
    //创建执行的销毁的方法
    public void destroyMethod() {
        System.out.println("第五步 执行销毁的方法");
    }
}

    
    @Test
    public void testBean3() {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("bean.xml");
        Orders orders = context.getBean("orders", Orders.class);
        System.out.println("第四步 获取创建 bean 实例对象");
        System.out.println(orders);
        //手动让 bean 实例销毁
        context.close();
    }

 10、添加后置处理器之后,Bean的生命周期有7步:

(1)通过无参构造创建 Bean 实例

(2)调用set方法为 Bean 的属性设置值和对其他 bean 引用

(3)把 Bean 实例传递 Bean 后置处理器的方法 postProcessBeforeInitialization

(4)调用 Bean 的初始化的方法(配置初始化的方法)

(5)把 Bean 实例传递 Bean 后置处理器的方法 postProcessAfterInitialization

(6)使用Bean(对象获取到了)

(7)当容器关闭时候,调用 Bean的销毁的方法(配置销毁的方法)

演示过程如下:

public class MyBeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前执行的方法");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之后执行的方法");
        return bean;
    }
}
    
    

 Bean的装配方式:

        Bean 的装配可以理解为将 Bean 依赖注入到 Spring 容器中,Bean 的装配方式即 Bean 依赖注入的方式。Spring 容器支持基于 XML 配置的装配、基于注解的装配以及自动装配等多种装配方式,其中最受亲睐的还是基于注解的装配。

一、基于xml自动装配

(1)什么是自动装配?

根据指定的装配规则【属性名称或者属性类型】,spring自动将匹配的属性进行注入;

(2)操作演示如下:

        <1>根据属性名称自动注入;

autowire中的byName是根据属性名注入,要注意注入值bean的id值要和类中的属性名称一样;

    
    

        <2>根据属性类型自动注入

    
     
    
         
        
    
    
    @Test
    public void test4(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        Emp emp = context.getBean("emp", Emp.class);
        System.out.println(emp);

    }
二、基于注解的装配 1、注解格式、作用范围、作用:

(1)格式:@注解名称(属性名称=属性值,...)

(2)作用范围:注解作用在类上面,方法上面,属性上面

(3)作用:简化 xml 配置

2、Spring 针对 Bean 管理中创建Bean对象提供如下注解:

(1)@Component:实现Bean的注入;以下3个是@Component的衍生注解(功能一样)

(2)@Service:service层

(3)@Controller:web层

(4)@Repository:dao层

3、基于注解方式实现对象创建:

        <1>引入依赖

        <2>在xml配置文件中开启组件扫描:


        <3>创建类,在类上面添加创建对象注解:

//在注解里面 value 属性值可以省略不写,
//默认值是类名称,首字母小写
//UserService -- userService
@Component//
public class UserService {
  //创建 UserDao 类型属性,生成对应的set方法
  private UserDao userDao;
  public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
  }
  public void add() {
    System.out.println("service add.........");
    userDao.update();
  }
}

        <4>开启组件扫描细节配置:

    
    
        
    
    
    
        
    
4、基于注解方式实现属性注入:

(1)@Autowired:该注解可以对类成员变量、方法及构造方法进行标注,完成自动装配的工作。通过使用@Autowired 来消除 setter 和 getter 方法。默认按照 Bean 的类型进行装配。

        <1>把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解;

        <2>在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解;

@Service
public class UserService {
 //定义 dao 类型属性
 //不需要添加 set 方法
 //添加注入属性注解
 @Autowired
 private UserDao userDao;
 public void add() {
 System.out.println("service add.......");
 userDao.add();
 }
}

(2)@Qualifier:该注解与 @Autowired 注解配合使用。当@Autowired 注解需要按照名称来装配注入时需要和该注解一起使用,Bean 的实例名称由@Qualifier 注解的参数指定。

@Service
public class UserService {
    //定义 dao 类型属性
    //不需要添加 set 方法
    //添加注入属性注解
    @Autowired //根据类型进行注入
    @Qualifier(value = "userDaoImpl1") //根据名称进行注入
    private UserDao userDao;
    public void add() {
         System.out.println("service add.......");
         userDao.add();
     }
}

(3)@Resource:该注解与@Autowired 的功能一样,区别在于该注解默认是按照名称来装配注入的,只有当找不到名称匹配的 Bean 时才会按照类型来装配注入;而@Autowired 默认按照 Bean 的类型进行装配,如果想按照名称来装配注入,则需要和@Qualifier 注解一起使用;
@Resource 注解有两个属性,name和type。name 属性指定 Bean 实例名称,即按照名称来装配注入;type 属性指定 Bean 的类型,即按照 Bean 的类型进行装配。

@Resource(name = "userDaoImpl1") //根据名称进行注入
private UserDao userDao;

(4)@Value:注入普通类型属性

@Value(value = "abc")
private String name;
AOP详解:【重点】 1、什么是AOP?

        AOP即面向切面编程,它与OOP面向对象编程相辅相成,提供了与 OOP 不同的抽象软件结构的视角。在 OOP 中,以类作为程序的基本单元,而 AOP 中的基本单元是Aspect(切面)。Struts2 的拦截器设计就是基于 AOP 的思想。

2、为什么使用AOP?

        利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

        也就是说,我们可以不修改源代码,在主干功能里面添加新功能即可。

3、AOP底层原理(动态代理):

(1)有接口情况,使用 JDK 动态代理:

实现动态代理的步骤:

        <1>创建接口,定义目标类要完成的功能

        <2>创建目标类实现接口

        <3>创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
                (1)调用目标方法
                (2)增强功能

        <4>使用Proxy类的静态方法,创建代理对象。 并把返回值转为接口类型。

        <5>通过代理调用方法

创建接口:【需要动态代理的接口】

public interface UserDao {
   public int add(int a,int b);
   public String update(String id);
}

创建接口实现类:【需要代理的实际对象】

public class UserDaoImpl implements UserDao {
   @Override
     public int add(int a, int b) {
     return a+b;
   }
   @Override
     public String update(String id) {
     return id;
   }
}

调用处理器实现类:每次生成动态代理类对象时都需要指定一个实现了该接口的调用处理器对象。

//创建代理对象代码
class UserDaoProxy implements InvocationHandler {
    //这个就是我们要代理的真实对象
    private Object obj;
    //有参构造,给我们要代理的真实对象赋初值
    public  UserDaoProxy(Object obj) {
        this.obj = obj;
    }

    
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     //在代理真实对象前我们可以添加一些自己的操作
     System.out.println("方法之前执行...."+method.getName()+" :传递的参数..."+ Arrays.toString(args));
     //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
     Object res = method.invoke(obj, args);
     //在代理真实对象后我们也可以添加一些自己的操作
     System.out.println("方法之后执行...."+obj);
     return res;
   }
}

测试:

public class JDKProxy {
    public static void main(String[] args) {
     //代理的真正对象
     UserDao userDao = new UserDaoImpl();
     
     InvocationHandler handler = new UserDaoProxy(userDao);
     //该方法用于为指定类装载器、接口及调用处理器生成动态代理类实例
     UserDao userDao1= (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), handler);
     System.out.println("动态代理对象的类型:"+userDao1.getClass().getName());
     int result = userDao1.add(1, 2);
     System.out.println("result:"+result);
    }
}

(2)没有接口情况,使用 CGLIB 动态代理(了解):

实现一个业务类,注意,这个业务类并没有实现任何接口:

public class HelloService {
 
    public HelloService() {
        System.out.println("HelloService构造");
    }
 
    //该方法不能被子类覆盖,Cglib是无法代理final修饰的方法的
    final public String sayOthers(String name) {
        System.out.println("HelloService:sayOthers>>"+name);
        return null;
    }
 
    public void sayHello() {
        System.out.println("HelloService:sayHello");
    }
}

自定义MethodInterceptor:

public class MyMethodInterceptor implements MethodInterceptor{
 
    
    @Override
    public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("增强前");
        Object object = methodProxy.invokeSuper(sub, objects);
        System.out.println("增强后");
        return object;
    }
}

生成CGLIB代理对象调用目标方法:

public class Client {
    public static void main(String[] args) {
        // 代理类class文件存入本地磁盘方便我们反编译查看源码
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\code");
        // 通过CGLIB动态代理获取代理对象的过程
        Enhancer enhancer = new Enhancer();
        // 设置enhancer对象的父类
        enhancer.setSuperclass(HelloService.class);
        // 设置enhancer的回调对象
        enhancer.setCallback(new MyMethodInterceptor());
        // 创建代理对象
        HelloService proxy= (HelloService)enhancer.create();
        // 通过代理对象调用目标方法
        proxy.sayHello();
    }
}
4、AOP常用的术语: (1)切面:

        切面是一个动作:把通知应用到切入点的过程。

(2)连接点:

        类里面哪些方法可以被增强,这些方法被称为连接点。

(3)切入点:

       实际被真正增强的方法称为切入点。


(4)通知:

        实际增强的逻辑部分被称为通知。

        常用类型:

        环绕通知:在目标方法执行前和执行后实施增强,可应用于日志记录、事物处理等功能。

        前置通知:前置通知是在目标方法执行前实施增强,可应用于权限管理等功能。

        后置通知:在目标方法成功执行后实施增强,可应用于关闭流、删除临时文件等功能。

5、AspectJ

        Spring框架一般都是基于AspectJ来实现AOP的操作:

(1)什么是AspectJ? 

AspectJ是一个AOP的框架,它不属于Spring;定义了AOP语法,是为了方便写AOP代码实现的;扩展了Java语言 (2)引入AOP相关依赖

        使用AspectJ 需要导入Spring AOP和 AspectJ相关jar包。

6、切入点表达式

        作用:知道对哪个类里面的哪个方法进行增强;

        语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )

        例 1:对 com.company.dao.BookDao 类里面的 add 进行增强;

execution(* com.company.dao.BookDao.add(..))

        例 2:对 com.company.dao.BookDao 类里面的所有的方法进行增强;

execution(* com.company.dao.BookDao.* (..))

        例 3:对 com.company.dao 包里面所有类,类里面所有方法进行增强;

execution(* com.company.dao.*.* (..))
7、AspectJ注解实现AOP

(1)创建增强类,在里面创建方法,让不同方法代表不同通知类型:

//增强的类
@Component
@Aspect //生成代理对象
public class UserProxy {
   //前置通知
   //@Before注解表示作为前置通知
   @Before(value = "execution(* com.company.User.add(..))")
   public void before() {
     System.out.println("before.........");
   }
}

(2)进行通知的配置:

        在 spring 配置文件中,开启注解扫描、开启生成代理对象;



    
    
    
    

(3)配置不同类型的通知:

        在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置;

//增强的类
@Component
@Aspect //生成代理对象
public class UserProxy {
   //前置通知
   //@Before注解表示作为前置通知
   @Before(value = "execution(* com.company.User.add(..))")
   public void before() {
     System.out.println("before.........");
   }
   //后置通知(返回通知)
   @AfterReturning(value = "execution(* com.company.User.add(..))")
   public void afterReturning() {
     System.out.println("afterReturning.........");
   }
   //最终通知
   @After(value = "execution(* com.company.User.add(..))")
   public void after() {
     System.out.println("after.........");
   }
   //异常通知
   @AfterThrowing(value = "execution(* com.company.User.add(..))")
   public void afterThrowing() {
     System.out.println("afterThrowing.........");
   }
   //环绕通知
   @Around(value = "execution(* com.company.User.add(..))")
   public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
     System.out.println("环绕之前.........");
     //被增强的方法执行
     proceedingJoinPoint.proceed();
     System.out.println("环绕之后.........");
   }
}

(4)相同的切入点抽取:

//相同切入点抽取
@Pointcut(value = "execution(* com.company.User.add(..))")
public void point() {
}
//前置通知
//@Before 注解表示作为前置通知
@Before(value = "point()")
public void before() {
   System.out.println("before.........");
}
......

(5)有多个增强类对同一个方法进行增强,设置增强类优先级:

        在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高;

//增强的类
@Component
@Aspect //生成代理对象
@Order(1)
public class UserProxy {
   //前置通知
   //@Before注解表示作为前置通知
   @Before(value = "execution(* com.company.User.add(..))")
   public void before() {
     System.out.println("before.........");
   }
  ......
}
8、xml配置实现Aop

(1)创建通知类,添加需要的方法;

public class User{
    // 前置通知
    public void before() {
        System.out.println("前置通知");
    }
    // 后置通知 始终会执行
    public void after() {
        System.out.println("后置通知");
    }
    // 环绕通知
    public void around(ProceedingJoinPoint proceedingJoinPoint ) throws Throwable {
        System.out.println("环绕通知前");
        proceedingJoinPoint .proceed();
        System.out.println("环绕通知后");
    }
    // 后置 发生异常时不会执行
    public void returning() {
        System.out.println("后置通知");
    }
    // 发生异常
    public void throwing() {
        System.out.println("发生异常");
    }
}

(2)在配置文件中添加通知类的Bean

 

(3)配置xml配置文件,添加,添加子标签


 




    
    
    
    
        
        
        
        
        
        
    

9、JdbcTemplate (1)什么是JdbcTemplate?

        我们都知道使用原始的JDBC在操作数据库是比较麻烦的,所以Spring为了提高开发的效率,把JDBC封装、改造了一番,而JdbcTemplate就是Spring对原始JDBC封装之后提供的一个操作数据库的工具类。

        我们可以借助JdbcTemplate来完成所有数据库操作,比如:增删改查等。改造之后的JdbcTemplate主要提供以下三种类型的方法:

    executeXxx() : 执行任何SQL语句,对数据库、表进行创建、修改、删除操作;updateXxx() : 执行增加、修改、删除等语句;queryXxx() : 执行查询相关的语句;

        "用之不强,但弃之可惜",为什么这么说呢?

        虽然JdbcTemplate算是最简单的数据持久层方案,属于另一种操作数据库的方式;但是从另一方面来说,实际开发过程中我们用的更多的是拥有更加强大的持久化框架来访问数据库,比如MyBatis、MyBatis Plus等。

(2)JdbcTemplate的基本使用

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

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

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