SpringIOC和AOP

打印 上一主题 下一主题

主题 891|帖子 891|积分 2673

1.  Spring概述

1.1. 什么是Spring

Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作 Expert One-On-One J2EE Development and Design 中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为J2EE应用程序开发提供集成的框架。Spring使用基本的 JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。 Spring的 核心是控制反转(IoC)和面向切面(AOP) 。简单来说, Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架。
EE开发分成三层结构

  • WEB层: Spring MVC
  • 业务层: Bean管理:(IOC)
  • 持久层: Spring的JDBC模板。ORM模板用于整合其他的持久层框架
Expert One-to-One J2EE Design and Development : J2EE 的设计和开发:(2002.EJB)Expert One-to-One J2EE Development without EJB : J2EE 不使用EJB的开发
1.2. 为什么学习Spring


  • 方便解耦,简化开发
Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理

  • AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能

  • 声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程

  • 方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序

  • 方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持

  • 降低JavaEE API的使用难度
Spring对JavaEE开发中非常难用的一些API(如:JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
1.3. Spring的版本

Spring3.X 和 Spring4.X 和 Spring5.X
1.4. spring功能模块划分


2.  JAVA类的耦合与解耦

2.1. 什么是程序的耦合

在开发中,可能会写很多的类,而有些类之间不可避免的产生依赖关系,这种依赖关系称之为耦合。
有些依赖关系是必须的,有些依赖关系可以通过优化代码来解除的。
代码示例
public class CustomerServiceImpl implements CustomerService {               CustomerDao cusomerDao = new CustomerDaoImpl();}
以上的代码表示:业务层调用持久层,并且此时业务层在依赖持久层的接口和实现类。如果此时没有持久层实现类,编译将不能通过。这种依赖关系就是我们可以通过优化代码解决的。
还有如下面的代码:
我们的类依赖了MySQL的具体驱动类,如果这时候因为某些原因数据库的品牌从MySQL改为Oracle,那么需要通过改源码来修改数据库驱动。这显然不是我们想要的。
public class JdbcDemo01{        public static void main(String[] args) throws Exception {               Class.forName("com.mysql.jdbc.Driver");               //new com.mysql.jdbc.Driver()        }}
2.2. 解决耦合的思路

当是我们学习JDBC时,是通过反射来注册驱动的,代码如下:
Class.forName("com.mysql.jdbc.Driver");
这时的好处是,我们的类中不再依赖具体的驱动类,此时就算删除mysql的驱动jar包,依然可以编译。但是因为没有驱动类,所以不能运行。
不过,此处也有个问题,就是我们反射类对象的全限定类名字符串是在java类中写死的,一旦要改还是要修改源码。
解决这个问题也很简单,使用配置文件配置。
2.2.1.  工厂模式解耦

在实际开发中我们可以把所有的dao和service和controller对象使用配置文件配置起来,当启动服务器应用加载的时候,通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。
2.2.2.  控制反转-Inversion Of Control

上面解耦的思路有2个问题:
1、存哪去?
分析:由于我们是很多对象,肯定要找个集合来存。这时候有Map和List供选择。
到底选Map还是List就看我们有没有查找需求。有查找需求,选Map。
所以我们的答案就是
在应用加载时,创建一个Map,用于存放controller,Service和dao对象。
我们把这个map称之为容器。
2、还是没解释什么是工厂?
工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。
原来:
我们在获取对象时,都是采用new的方式。是主动的。

现在:
我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。

这种被动接收的方式获取对象的思想就是控制反转,它是spring框架的核心之一。
它的作用只有一个:削减计算机程序的耦合。
3.  Spring的 IOC

3.1. 什么是IoC

Inversion of Control:控制权的转移,创建对象的权利由应用程序转移到容器称为控制反转
3.2. IoC的作用

削减计算机程序的耦合(解除我们代码中的依赖关系)
3.3. 基于XML的IoC配置入门

创建Maven项目,resources 创建spring配置文件

pom.xml依赖

    org.springframework
    spring-context
    5.3.8

编写UserService类
public class UserService {
    public UserService() {
        System.out.println("UserService()......");
    }

    public void add() {
        System.out.println("UserService.add()......");
    }
}
编写applicationContext.xml配置文件

   
   


 
编写测试类Test
public class Test {
    public static void main(String[] args) {
        //实例化ClassPathXmlApplicationContext对象,配置文件作为参数
       
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //上线文对象 getBean方法获取配置bean对象UserService
       
UserService userService = context.getBean(UserService.class);
        //调用UserServiceadd方法
       
userService.add();
    }
}
结果:

3.4. ApplicationContext

ApplicatioContext接口有两个基本的实现类:

ClassPathXmlApplicationContext : 加载类路径下的Spring配置文件。
FileSystemXmlApplicationContext : 加载本地磁盘下的Spring配置文件。
4.   Bean的配置

4.1. spring中的bean元素相关配置Spring中的bean元素相关配置

配置文件中的bean元素用于描述需要Spring容器管理的对象。其 class属性 用于指被管理对象的完整类名。
4.1.1.  id属性和name属性

id属性 是为Spring容器管理的对象起个名字。其使用ID约束:
唯一
必须以字母开始
可以使用字母、数字、连字符、下划线、句号、冒号。但 不能出现特殊字符
name属性 也是为被Spring容器管理的对象起个名字。这样后续可以通过该名字从容器中获取对象。
没有ID中的那些约束(可以重复[不推荐]、可以出现特殊字符)
如果没有id的话,name可以当做id使用
举例

 
此处的名称中由于有特殊字符,只能使用name属性。
结论:在定义bean的时候,推荐使用name属性 来为bean指定名称
4.1.2.  scope属性

用于声明bean在Spring容器中的作用范围。其取值包括:
singleton : 默认值 单例的;默认在Spring容器启动的时候就会创建该实例。
prototype : 多例的;默认在从Spring容器中获取bean时才会创建该实例。
request : WEB项目中,Spring创建一个Bean的对象,将对象存入到request域中。
session : WEB项目中,Spring创建一个Bean的对象,将对象存入到session域中。
globalSession : WEB项目中,应用在Porlet环境。如果没有Porlet环境,那么globalSession相当于session。
4.1.3.  生命周期属性

在bean被创建的时候,需要执行一些初始化的逻辑。可以指定bean中的一个方法为其初始化方法。这样Spring在创建完该对象之后,立即调用一下该初始化方法。
public void init() {
    System.out.println("UserService.init()......");
}

 
在bean对象销毁的时候,需要执行一些销毁逻辑。可以指定bean中的一个方法为其销毁方法。这样Spring容器在关闭之前并且销毁该对象的时候,会调用一下该销毁方法。
public void destroy() {
    System.out.println("UserService.destroy().......");
}
 

 
注意,此处的销毁方法必须是在容器正常关闭(即执行close方法)时,才会被执行。
4.2. Spring生成Bean的时候的三种方式

方式1:无参数的构造方法的方式
  1. [/code][b]方式[/b][b]2:[/b][b]静态工厂实例化的方式[/b]
  2. [code]
复制代码
  1. public class UserServiceFactory {
  2.     //静态工厂实例化的方式
  3.     public static UserService getBean(){
  4. <bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean>return new UserService();
  8.     }
  9. }
复制代码
方式3:实例工厂实例化的方式
  1. [/code][code]public class UserServiceFactory2 {
  2.     /*实例方法,要调用次方法,必须先创建UserServiceFactory2的实例对象*/
  3.     public UserService getBean2() {
  4. <bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean>return new UserService();
  8.     }
  9. }
复制代码
4.3. Spring中Bean属性的注入

4.3.1.  方式1:构造方法的方式注入属性

定义Car
  1. public class Car {
  2.     private String name;
  3.     private int price;
  4.     public Car(String name, int price) {
  5. <bean id="car" >
  6.     <constructor-arg name="name" value="carat"></constructor-arg>
  7.     <constructor-arg name="price" value="17526"></constructor-arg>
  8. </bean>this.name = name;
  9. <bean id="car" >
  10.     <constructor-arg name="name" value="carat"></constructor-arg>
  11.     <constructor-arg name="price" value="17526"></constructor-arg>
  12. </bean>this.price = price;
  13.     }
  14.     public String getName() { return name;}
  15.     public void setName(String name) { this.name = name;}
  16.     public int getPrice() { return price; }
  17.     public void setPrice(int price) {this.price = price;}
  18.     @Override
  19.     public String toString() {
  20. <bean id="car" >
  21.     <constructor-arg name="name" value="carat"></constructor-arg>
  22.     <constructor-arg name="price" value="17526"></constructor-arg>
  23. </bean>return "Car{" + "name='" + name + '\'' + ", price=" + price +  '}';
  24.     }
  25. }
复制代码
Spring配置Car
  1. <bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean>
复制代码
测试
  1. public class Test {    public static void main(String[] args) {<bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean>ClassPathXmlApplicationContext context =<bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean><bean id="car" >
  8.     <constructor-arg name="name" value="carat"></constructor-arg>
  9.     <constructor-arg name="price" value="17526"></constructor-arg>
  10. </bean>new ClassPathXmlApplicationContext("applicationContext.xml");<bean id="car" >
  11.     <constructor-arg name="name" value="carat"></constructor-arg>
  12.     <constructor-arg name="price" value="17526"></constructor-arg>
  13. </bean>Car car = (Car) context.getBean("car");<bean id="car" >
  14.     <constructor-arg name="name" value="carat"></constructor-arg>
  15.     <constructor-arg name="price" value="17526"></constructor-arg>
  16. </bean>System.out.println(car);    }}
复制代码
4.3.2.  方式2:set方法的方式注入属性

基本类型的属性注入
定义Car
  1. public class Car {    private String name;    private int price;    public Car() {    }    public Car(String name, int price) {<bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean>this.name = name;<bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean>this.price = price;    }    public String getName() { return name;}    public void setName(String name) { this.name = name;}    public int getPrice() { return price; }    public void setPrice(int price) {this.price = price;}    @Override    public String toString() {<bean id="car" >
  8.     <constructor-arg name="name" value="carat"></constructor-arg>
  9.     <constructor-arg name="price" value="17526"></constructor-arg>
  10. </bean>return "Car{" + "name='" + name + '\'' + ", price=" + price +  '}';    }}
复制代码
Spring配置
  1. <bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean><bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean><bean id="car" >
  8.     <constructor-arg name="name" value="carat"></constructor-arg>
  9.     <constructor-arg name="price" value="17526"></constructor-arg>
  10. </bean>   
复制代码
测试
  1. public class Test {    public static void main(String[] args) {<bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean>ClassPathXmlApplicationContext context =<bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean><bean id="car" >
  8.     <constructor-arg name="name" value="carat"></constructor-arg>
  9.     <constructor-arg name="price" value="17526"></constructor-arg>
  10. </bean>new ClassPathXmlApplicationContext("applicationContext1.xml");<bean id="car" >
  11.     <constructor-arg name="name" value="carat"></constructor-arg>
  12.     <constructor-arg name="price" value="17526"></constructor-arg>
  13. </bean>Car car = (Car) context.getBean("car1");//根据配置的id 获取car对象<bean id="car" >
  14.     <constructor-arg name="name" value="carat"></constructor-arg>
  15.     <constructor-arg name="price" value="17526"></constructor-arg>
  16. </bean>System.out.println(car);    }}
复制代码

对象类型的属性注入
定义Person
  1. public class Person {    private String name;    private Car car;    public String getName() {return name; }    public void setName(String name) {this.name = name;}    public Car getCar() { return car;}    public void setCar(Car car) {this.car = car; }    @Override    public String toString() {<bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean>return "Person{" + "name='" + name + '\'' + ", car=" + car + '}';    }}
复制代码
Spring配置
  1. <bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean><bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean><bean id="car" >
  8.     <constructor-arg name="name" value="carat"></constructor-arg>
  9.     <constructor-arg name="price" value="17526"></constructor-arg>
  10. </bean>
复制代码
测试:
  1. public class Test{
  2.     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext1.xml");
  3.     //根据配置的id 获取Person对象
  4.     Person person = (Person) context.getBean("person");
  5.     System.out.println(person);
  6. }
复制代码
 
4.4. 在配置文件中引入Properties配置

方案1:配置Spring的Bean PropertySourcesPlaceholderConfigurer
  1. <bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean><bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean><bean id="car" >
  8.     <constructor-arg name="name" value="carat"></constructor-arg>
  9.     <constructor-arg name="price" value="17526"></constructor-arg>
  10. </bean><bean id="car" >
  11.     <constructor-arg name="name" value="carat"></constructor-arg>
  12.     <constructor-arg name="price" value="17526"></constructor-arg>
  13. </bean><bean id="car" >
  14.     <constructor-arg name="name" value="carat"></constructor-arg>
  15.     <constructor-arg name="price" value="17526"></constructor-arg>
  16. </bean>classpath*:db.properties<bean id="car" >
  17.     <constructor-arg name="name" value="carat"></constructor-arg>
  18.     <constructor-arg name="price" value="17526"></constructor-arg>
  19. </bean><bean id="car" >
  20.     <constructor-arg name="name" value="carat"></constructor-arg>
  21.     <constructor-arg name="price" value="17526"></constructor-arg>
  22. </bean><bean id="car" >
  23.     <constructor-arg name="name" value="carat"></constructor-arg>
  24.     <constructor-arg name="price" value="17526"></constructor-arg>
  25. </bean>
复制代码
  1. <bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean><bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean><bean id="car" >
  8.     <constructor-arg name="name" value="carat"></constructor-arg>
  9.     <constructor-arg name="price" value="17526"></constructor-arg>
  10. </bean>
复制代码
方案2:引入 context名称空间 。使用context中提供的  指定它的 location 属性值,如果有多个文件,使用 逗号 分割。
  1. [/code] 
  2. [table][tr][td=1,1,553]
  3.    
  4.    
  5.    
  6.    
  7. [/td][/tr][/table]classpath:xx 这种写法,只会搜索到文件夹类型的下面的资源。不会搜索到jar包中的。
  8. classpath*:xx 这种写法,都会搜索到。所以【推荐用这种】
  9. [size=5]4.5. 复杂类型的注入[/size]
  10. 定义CollectionDemo
  11. [code]package com.tjetc.entity;import java.util.Arrays;import java.util.List;import java.util.Map;import java.util.Properties;public class CollectionDemo {    private String[] strs;    private List list;    private Map map;    private Properties properties;    public String[] getStrs() {<bean id="car" >
  12.     <constructor-arg name="name" value="carat"></constructor-arg>
  13.     <constructor-arg name="price" value="17526"></constructor-arg>
  14. </bean>return strs;    }    public void setStrs(String[] strs) {<bean id="car" >
  15.     <constructor-arg name="name" value="carat"></constructor-arg>
  16.     <constructor-arg name="price" value="17526"></constructor-arg>
  17. </bean>this.strs = strs;    }    public List getList() {<bean id="car" >
  18.     <constructor-arg name="name" value="carat"></constructor-arg>
  19.     <constructor-arg name="price" value="17526"></constructor-arg>
  20. </bean>return list;    }    public void setList(List list) {<bean id="car" >
  21.     <constructor-arg name="name" value="carat"></constructor-arg>
  22.     <constructor-arg name="price" value="17526"></constructor-arg>
  23. </bean>this.list = list;    }    public Map getMap() {<bean id="car" >
  24.     <constructor-arg name="name" value="carat"></constructor-arg>
  25.     <constructor-arg name="price" value="17526"></constructor-arg>
  26. </bean>return map;    }    public void setMap(Map map) {<bean id="car" >
  27.     <constructor-arg name="name" value="carat"></constructor-arg>
  28.     <constructor-arg name="price" value="17526"></constructor-arg>
  29. </bean>this.map = map;    }    public Properties getProperties() {<bean id="car" >
  30.     <constructor-arg name="name" value="carat"></constructor-arg>
  31.     <constructor-arg name="price" value="17526"></constructor-arg>
  32. </bean>return properties;    }    public void setProperties(Properties properties) {<bean id="car" >
  33.     <constructor-arg name="name" value="carat"></constructor-arg>
  34.     <constructor-arg name="price" value="17526"></constructor-arg>
  35. </bean>this.properties = properties;    }    @Override    public String toString() {<bean id="car" >
  36.     <constructor-arg name="name" value="carat"></constructor-arg>
  37.     <constructor-arg name="price" value="17526"></constructor-arg>
  38. </bean>return "CollectionDemo{" +<bean id="car" >
  39.     <constructor-arg name="name" value="carat"></constructor-arg>
  40.     <constructor-arg name="price" value="17526"></constructor-arg>
  41. </bean><bean id="car" >
  42.     <constructor-arg name="name" value="carat"></constructor-arg>
  43.     <constructor-arg name="price" value="17526"></constructor-arg>
  44. </bean>"strs=" + Arrays.toString(strs) +<bean id="car" >
  45.     <constructor-arg name="name" value="carat"></constructor-arg>
  46.     <constructor-arg name="price" value="17526"></constructor-arg>
  47. </bean><bean id="car" >
  48.     <constructor-arg name="name" value="carat"></constructor-arg>
  49.     <constructor-arg name="price" value="17526"></constructor-arg>
  50. </bean>", list=" + list +<bean id="car" >
  51.     <constructor-arg name="name" value="carat"></constructor-arg>
  52.     <constructor-arg name="price" value="17526"></constructor-arg>
  53. </bean><bean id="car" >
  54.     <constructor-arg name="name" value="carat"></constructor-arg>
  55.     <constructor-arg name="price" value="17526"></constructor-arg>
  56. </bean>", map=" + map +<bean id="car" >
  57.     <constructor-arg name="name" value="carat"></constructor-arg>
  58.     <constructor-arg name="price" value="17526"></constructor-arg>
  59. </bean><bean id="car" >
  60.     <constructor-arg name="name" value="carat"></constructor-arg>
  61.     <constructor-arg name="price" value="17526"></constructor-arg>
  62. </bean>", properties=" + properties +<bean id="car" >
  63.     <constructor-arg name="name" value="carat"></constructor-arg>
  64.     <constructor-arg name="price" value="17526"></constructor-arg>
  65. </bean><bean id="car" >
  66.     <constructor-arg name="name" value="carat"></constructor-arg>
  67.     <constructor-arg name="price" value="17526"></constructor-arg>
  68. </bean>'}';    }}
复制代码
Spring配置
  1. <bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean><bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean><bean id="car" >
  8.     <constructor-arg name="name" value="carat"></constructor-arg>
  9.     <constructor-arg name="price" value="17526"></constructor-arg>
  10. </bean>    张三<bean id="car" >
  11.     <constructor-arg name="name" value="carat"></constructor-arg>
  12.     <constructor-arg name="price" value="17526"></constructor-arg>
  13. </bean>    李四<bean id="car" >
  14.     <constructor-arg name="name" value="carat"></constructor-arg>
  15.     <constructor-arg name="price" value="17526"></constructor-arg>
  16. </bean><bean id="car" >
  17.     <constructor-arg name="name" value="carat"></constructor-arg>
  18.     <constructor-arg name="price" value="17526"></constructor-arg>
  19. </bean><bean id="car" >
  20.     <constructor-arg name="name" value="carat"></constructor-arg>
  21.     <constructor-arg name="price" value="17526"></constructor-arg>
  22. </bean><bean id="car" >
  23.     <constructor-arg name="name" value="carat"></constructor-arg>
  24.     <constructor-arg name="price" value="17526"></constructor-arg>
  25. </bean><bean id="car" >
  26.     <constructor-arg name="name" value="carat"></constructor-arg>
  27.     <constructor-arg name="price" value="17526"></constructor-arg>
  28. </bean>jack<bean id="car" >
  29.     <constructor-arg name="name" value="carat"></constructor-arg>
  30.     <constructor-arg name="price" value="17526"></constructor-arg>
  31. </bean>    lucy<bean id="car" >
  32.     <constructor-arg name="name" value="carat"></constructor-arg>
  33.     <constructor-arg name="price" value="17526"></constructor-arg>
  34. </bean><bean id="car" >
  35.     <constructor-arg name="name" value="carat"></constructor-arg>
  36.     <constructor-arg name="price" value="17526"></constructor-arg>
  37. </bean><bean id="car" >
  38.     <constructor-arg name="name" value="carat"></constructor-arg>
  39.     <constructor-arg name="price" value="17526"></constructor-arg>
  40. </bean><bean id="car" >
  41.     <constructor-arg name="name" value="carat"></constructor-arg>
  42.     <constructor-arg name="price" value="17526"></constructor-arg>
  43. </bean><bean id="car" >
  44.     <constructor-arg name="name" value="carat"></constructor-arg>
  45.     <constructor-arg name="price" value="17526"></constructor-arg>
  46. </bean><bean id="car" >
  47.     <constructor-arg name="name" value="carat"></constructor-arg>
  48.     <constructor-arg name="price" value="17526"></constructor-arg>
  49. </bean><bean id="car" >
  50.     <constructor-arg name="name" value="carat"></constructor-arg>
  51.     <constructor-arg name="price" value="17526"></constructor-arg>
  52. </bean><bean id="car" >
  53.     <constructor-arg name="name" value="carat"></constructor-arg>
  54.     <constructor-arg name="price" value="17526"></constructor-arg>
  55. </bean><bean id="car" >
  56.     <constructor-arg name="name" value="carat"></constructor-arg>
  57.     <constructor-arg name="price" value="17526"></constructor-arg>
  58. </bean><bean id="car" >
  59.     <constructor-arg name="name" value="carat"></constructor-arg>
  60.     <constructor-arg name="price" value="17526"></constructor-arg>
  61. </bean><bean id="car" >
  62.     <constructor-arg name="name" value="carat"></constructor-arg>
  63.     <constructor-arg name="price" value="17526"></constructor-arg>
  64. </bean>    111<bean id="car" >
  65.     <constructor-arg name="name" value="carat"></constructor-arg>
  66.     <constructor-arg name="price" value="17526"></constructor-arg>
  67. </bean>    222<bean id="car" >
  68.     <constructor-arg name="name" value="carat"></constructor-arg>
  69.     <constructor-arg name="price" value="17526"></constructor-arg>
  70. </bean>   
复制代码
测试:
  1. public class Test {    public static void main(String[] args) {<bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean>ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext1.xml");<bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean>CollectionDemo demo = (CollectionDemo) context.getBean("collectionDemo");<bean id="car" >
  8.     <constructor-arg name="name" value="carat"></constructor-arg>
  9.     <constructor-arg name="price" value="17526"></constructor-arg>
  10. </bean>System.out.println(demo);}
复制代码
4.6. Spring的分配置文件开发

随着项目越来越大,Spring的配置文件的内容也会越来越多。在实际的开发中,会将不同的配置定义在不同的xml文件中。有两种使用方式:
方式1:在创建容器的时候加载多个配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml","propertiesContext.xml");
方式2:在主配置文件中包含其它配置文件(推荐使用)

propertiesContext.xml
  1. <bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean><bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean><bean id="car" >
  8.     <constructor-arg name="name" value="carat"></constructor-arg>
  9.     <constructor-arg name="price" value="17526"></constructor-arg>
  10. </bean><bean id="car" >
  11.     <constructor-arg name="name" value="carat"></constructor-arg>
  12.     <constructor-arg name="price" value="17526"></constructor-arg>
  13. </bean><bean id="car" >
  14.     <constructor-arg name="name" value="carat"></constructor-arg>
  15.     <constructor-arg name="price" value="17526"></constructor-arg>
  16. </bean>
复制代码
applicationContext.xml
  1. <bean id="car" >
  2.     <constructor-arg name="name" value="carat"></constructor-arg>
  3.     <constructor-arg name="price" value="17526"></constructor-arg>
  4. </bean><bean id="car" >
  5.     <constructor-arg name="name" value="carat"></constructor-arg>
  6.     <constructor-arg name="price" value="17526"></constructor-arg>
  7. </bean>   
复制代码
5.  Spring注解方式的Bean管理

主要解决的问题,在XML中一个一个对bean进行配置,开发效率也不高。
目的:

  • 自动发现哪些对象需要让Spring进行管理,自动将其注册到Spring容器中。
  • 自动注入bean依赖的内容。
5.1. Spring Bean管理中的常用注解

5.1.1.  准备工作

使用注解要先开启注解扫描的功能
  1. [/code][size=4]5.1.2.  @Component[/size]
  2. 标注在类上,说明这是一个Spring组件。Spring中目前还提供了与 @Component 功能一致的其它三个衍生注解:
  3. [list]
  4. [*]@Controller :WEB 层(控制层)
  5. [*]@Service :业务层
  6. [*]@Repository :持久层
  7. [/list]衍生的三个注解是为了让标注类本身的用途清晰,Spring在后续版本会对其增强
  8. 作用和XML配置文件的标签的实现功能一致;
  9. [size=4]5.1.3.  属性注入的注解[/size]
  10. 使用注解注入的方式,可以不用提供set方法。
  11. [b]相关注解[/b]
  12. [list]
  13. [*][b]@Value : [/b][b]用于注入普通类型和String类型。[/b]
  14. [list]
  15. [*][b]加在成员变量上[/b][b]——[/b][b]原理是反射赋值(破坏封装)[/b]
  16. [*][b]加在[/b][b]set[/b][b]方法上[/b][b]——[/b][b]原理是方法调用(推荐使用)[/b]
  17. [*][b]它可以使用spring中的spEL(也就是spring的el表达式),SpEl的写法:${表达式}[/b]
  18. [/list]
  19. [/list]@Value使用
  20. [code]package com.tjetc.common;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;@Component("adminConstant") //小括号字符串是AdminConstant类的bean的名称public class AdminConstant {    //@Value可以把配置数据注入到成员变量或者setXXX方法,前提条件:spring要对类实例化并管理    //@Value 通过${} 读取key对应的value数据    @Value("${img.base.path}")    private String basePath;    @Value("111111111")    private String abc;    private String baseType;    @Value("${img.base.type}")    public void setBaseType(String baseType) {<bean id="car" >
  21.     <constructor-arg name="name" value="carat"></constructor-arg>
  22.     <constructor-arg name="price" value="17526"></constructor-arg>
  23. </bean>this.baseType = baseType;    }    public String getBasePath() {<bean id="car" >
  24.     <constructor-arg name="name" value="carat"></constructor-arg>
  25.     <constructor-arg name="price" value="17526"></constructor-arg>
  26. </bean>return basePath;    }    public void setBasePath(String basePath) {<bean id="car" >
  27.     <constructor-arg name="name" value="carat"></constructor-arg>
  28.     <constructor-arg name="price" value="17526"></constructor-arg>
  29. </bean>this.basePath = basePath;    }    public String getBaseType() {<bean id="car" >
  30.     <constructor-arg name="name" value="carat"></constructor-arg>
  31.     <constructor-arg name="price" value="17526"></constructor-arg>
  32. </bean>return baseType;    }    public String getAbc() {<bean id="car" >
  33.     <constructor-arg name="name" value="carat"></constructor-arg>
  34.     <constructor-arg name="price" value="17526"></constructor-arg>
  35. </bean>return abc;    }    public void setAbc(String abc) {<bean id="car" >
  36.     <constructor-arg name="name" value="carat"></constructor-arg>
  37.     <constructor-arg name="price" value="17526"></constructor-arg>
  38. </bean>this.abc = abc;    }    @Override    public String toString() {<bean id="car" >
  39.     <constructor-arg name="name" value="carat"></constructor-arg>
  40.     <constructor-arg name="price" value="17526"></constructor-arg>
  41. </bean>return "AdminConstant{" +<bean id="car" >
  42.     <constructor-arg name="name" value="carat"></constructor-arg>
  43.     <constructor-arg name="price" value="17526"></constructor-arg>
  44. </bean><bean id="car" >
  45.     <constructor-arg name="name" value="carat"></constructor-arg>
  46.     <constructor-arg name="price" value="17526"></constructor-arg>
  47. </bean>"basePath='" + basePath + '\'' +<bean id="car" >
  48.     <constructor-arg name="name" value="carat"></constructor-arg>
  49.     <constructor-arg name="price" value="17526"></constructor-arg>
  50. </bean><bean id="car" >
  51.     <constructor-arg name="name" value="carat"></constructor-arg>
  52.     <constructor-arg name="price" value="17526"></constructor-arg>
  53. </bean>", abc='" + abc + '\'' +<bean id="car" >
  54.     <constructor-arg name="name" value="carat"></constructor-arg>
  55.     <constructor-arg name="price" value="17526"></constructor-arg>
  56. </bean><bean id="car" >
  57.     <constructor-arg name="name" value="carat"></constructor-arg>
  58.     <constructor-arg name="price" value="17526"></constructor-arg>
  59. </bean>", baseType='" + baseType + '\'' +<bean id="car" >
  60.     <constructor-arg name="name" value="carat"></constructor-arg>
  61.     <constructor-arg name="price" value="17526"></constructor-arg>
  62. </bean><bean id="car" >
  63.     <constructor-arg name="name" value="carat"></constructor-arg>
  64.     <constructor-arg name="price" value="17526"></constructor-arg>
  65. </bean>'}';    }}
复制代码
applicationContext.xml配置
  1. [/code]测试
  2. [table][tr][td=1,1,553][b]public class [/b]Test2 {
  3.     [b]public static void [/b]main(String[] args) {
  4.         ClassPathXmlApplicationContext context = [b]new [/b]ClassPathXmlApplicationContext([b]"applicationContext.xml"[/b]);
  5.         AdminConstant constant = (AdminConstant) context.getBean([b]"constant"[/b]);
  6.         System.[b][i]out[/i][/b].println(constant);
  7.     }
  8. }
  9. [/td][/tr][/table] 
  10.  
  11. [list]
  12. [*][b]@Autowired : [/b][b]用于注入对象类型(自动装配)[/b]
  13. [list]
  14. [*][b]默认按类型进行装配[/b]
  15. [*][b]按名称注入[/b][b]: @Qualifier——[/b][b]强制使用名称注入,一般不能单独使用和Autowired配合使用,当注入的对象类型有多个时,@Autowoired必须与[/b][b]@Qualifier[/b][b]一起使用[/b]
  16. [/list]
  17. [/list]@Autowoired和@Qualifier使用
  18. [table][tr][td=1,1,553][b]public class [/b]User {
  19.     [b]private [/b]Long [b]id[/b];
  20.     [b]public void [/b]setId(Long id) {
  21.         [b]this[/b].[b]id [/b]= id;
  22.     }
  23.     @Override
  24.     [b]public [/b]String toString() {
  25.         [b]return [/b][b]"User{" [/b]+
  26.                 [b]"id=" [/b]+ [b]id [/b]+
  27.                 [b]'}'[/b];
  28.     }
  29. }
  30.  
  31. [/td][/tr][/table] 
  32. applicationContext.xml配置
  33. [table][tr][td=1,1,553]
  34.    
  35.    
  36. [/td][/tr][/table]PrintUser.java
  37. [table][tr][td=1,1,553]@Component
  38. [b]public class [/b]PrintUser {
  39.     @Autowired
  40.     @Qualifier([b]"user1"[/b])
  41. [b]    private [/b]User [b]user[/b];
  42.     [b]public void [/b]print(){
  43.         System.[b][i]out[/i][/b].println([b]user[/b]);
  44.     }
  45. }
  46.  
  47. [/td][/tr][/table]测试
  48. [table][tr][td=1,1,553][b]public class [/b]TestPrintUser {
  49.     [b]public static void [/b]main(String[] args) {
  50.         ClassPathXmlApplicationContext context = [b]new [/b]ClassPathXmlApplicationContext([b]"applicationContext.xml"[/b]);
  51.         PrintUser printUser = (PrintUser) context.getBean([b]"printUser"[/b]);
  52.         printUser.print();
  53.     }
  54. }
  55. [/td][/tr][/table] 
  56. [list]
  57. [*][b]@Resource : [/b][b]相当于[/b][b]@Autowired[/b][b]和[/b][b]@Qualifier[/b][b]一起使用[/b]
  58. [/list][table][tr][td=1,1,553]@Component
  59. [b]public class [/b]PrintUser {
  60.   [i]
  61.     [/i]@Resource(name = [b]"user2"[/b])
  62.     [b]private [/b]User [b]user[/b];
  63.     [b]public void [/b]print(){
  64.         System.[b][i]out[/i][/b].println([b]user[/b]);
  65.     }
  66. }
  67. [/td][/tr][/table] 
  68. 测试:
  69. [table][tr][td=1,1,553][b]public class [/b]TestPrintUser {
  70.     [b]public static void [/b]main(String[] args) {
  71.         ClassPathXmlApplicationContext context = [b]new [/b]ClassPathXmlApplicationContext([b]"applicationContext.xml"[/b]);
  72.         PrintUser printUser = (PrintUser) context.getBean([b]"printUser"[/b]);
  73.         printUser.print();
  74.     }
  75. }
  76.  
  77. [/td][/tr][/table] 
  78. [size=4]5.1.4.  Bean的作用范围的注解[/size]
  79. [b]注解[/b][b]@Scope[/b]
  80. [list]
  81. [*]singleton : 单例
  82. [*]prototype : 多例
  83. [/list][table][tr][td=1,1,553]@Service
  84. @Scope([b]"prototype"[/b])
  85. [b]public class [/b]ProductServiceImpl {
  86.    [b]public [/b]ProductServiceImpl(){
  87.     System.[b][i]out[/i][/b].println([b]"ProductServiceImpl()[/b][b]构造方法[/b][b]....."[/b]);
  88.   }}
  89. [/td][/tr][/table]测试
  90. [table][tr][td=1,1,553][b]public class [/b]TestProductService {
  91.     [b]public static void [/b]main(String[] args) {
  92.         ClassPathXmlApplicationContext context = [b]new [/b]ClassPathXmlApplicationContext([b]"applicationContext.xml"[/b]);
  93.         ProductServiceImpl productService1 = context.getBean(ProductServiceImpl.[b]class[/b]);
  94.         ProductServiceImpl productService2= context.getBean(ProductServiceImpl.[b]class[/b]);
  95.         System.[b][i]out[/i][/b].println(productService1==productService2);
  96.     }
  97. }
  98. [/td][/tr][/table] 
  99. [size=4]5.1.5.  Bean的生命周期的配置[/size]
  100. [b]相关注解[/b]
  101. [list]
  102. [*]@PostConstruct : 相当于init-method
  103. [*]@PreDestroy : 相当于destroy-method
  104. [/list] 
  105. [table][tr][td=1,1,553]@Service
  106. [b]public class [/b]ProductServiceImpl {
  107.     [b]public [/b]ProductServiceImpl(){
  108.         System.[b][i]out[/i][/b].println([b]"ProductServiceImpl()[/b][b]构造方法[/b][b]....."[/b]);
  109.     }
  110.     @PostConstruct
  111.     [b]public void [/b]init(){
  112.         System.[b][i]out[/i][/b].println([b]"ProductServiceImpl.init()....."[/b]);
  113.     }
  114.     @PreDestroy
  115.     [b]public void [/b]destroy(){
  116.         System.[b][i]out[/i][/b].println([b]"ProductServiceImpl.destroy()......"[/b]);
  117.     }
  118. }
  119. [/td][/tr][/table]测试
  120. [table][tr][td=1,1,553][b]public class [/b]TestProductService {
  121.     [b]public static void [/b]main(String[] args) {
  122.         ClassPathXmlApplicationContext context = [b]new [/b]ClassPathXmlApplicationContext([b]"applicationContext.xml"[/b]);
  123.         ProductServiceImpl productService = context.getBean(ProductServiceImpl.[b]class[/b]);
  124.         context.close();[i]
  125.     [/i]}
  126. }
  127. [/td][/tr][/table][size=6]6.  AOP的概述[/size]
  128. Aop思想
  129. [img]https://img2022.cnblogs.com/blog/2791316/202206/2791316-20220624202639759-2005049107.png[/img]
  130. [size=5]6.1. 什么是AOP[/size]
  131. [img]https://img2022.cnblogs.com/blog/2791316/202206/2791316-20220624202654527-455422639.png[/img]
  132. [b]Spring[/b][b]是解决实际开发中的一些问题:[/b]
  133. [list]
  134. [*]AOP解决OOP中遇到的一些问题。是OOP的延续和扩展。
  135. [*]Spring引入AOP思想来为容器中管理的对象动态生成代理对象。
  136. [/list][size=5]6.2. 为什么学习AOP[/size]
  137. [b]AOP[/b][b]的常用应用场景[/b]
  138. [list]
  139. [*]权限校验
  140. [*]日志记录
  141. [*]性能监控
  142. [*]事务控制
  143. [/list][size=5]6.3. Spring的AOP的由来[/size]
  144. AOP最早由AOP联盟的组织提出的,制定了一套规范。Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范。
  145. [size=5]6.4. 底层实现[/size]
  146. [b]Spring[/b][b]的AOP底层用到两种代理机制[/b]
  147. [list]
  148. [*][b]JDK[/b]的动态代理 : 针对实现了接口的类产生代理。
  149. [list]
  150. [*]被代理的类必须要实现接口,才能产生代理对象。如果没有接口将不能使用动态代理技术。
  151. [/list]
  152. [*][b]Cglib[/b]的动态代理 : 针对没有实现接口的类产生代理。应用的是底层的字节码增强的技术生成当前类的子类对象。
  153. [list]
  154. [*]可以对任何[b]非[/b][b]final[/b][b]声明的[/b] 类生成代理。
  155. [/list]
  156. [/list][size=6]7.  Spring AOP基于XML实现[/size]
  157. [size=5]7.1. AOP开发中的相关术语[/size]
  158. [b]Joinpoint([/b][b]连接点[/b][b])[/b] : 所谓连接点是指 那些被拦截到的点 。在Spring中,这些点指的是方法。
  159. [b]Pointcut([/b][b]切入点[/b][b])[/b] : 所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
  160. [b]Advice([/b][b]通知[/b][b]/[/b][b]增强[/b][b])[/b] : 所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。通知分为前置通知、后置 通知、异常通知、最终通知、环绕通知(切面要完成的功能)。
  161. [b]Aspect([/b][b]切面[/b][b])[/b] : 是切入点和通知(引介)的结合,即切入点+通知
  162. [size=5]7.2. 基于XML配置方式声明切面[/size]
  163. [size=4]7.2.1.  pom依赖[/size]
  164. [table][tr][td=1,1,553]
  165.     org.aspectj
  166.     aspectjweaver
  167.     1.9.7
  168. [/td][/tr][/table] 
  169. [size=4]7.2.2.  写切面类[/size]
  170. [table][tr][td=1,1,553]
  171. [b]public class [/b]TransactionPrint {
  172.     [b]public void [/b]doBefore() {
  173.         System.[b][i]out[/i][/b].println([b]"[/b][b]前置通知[/b][b]...."[/b]);
  174.     }
  175.     [b]public void [/b]doAfterReturning() {
  176.         System.[b][i]out[/i][/b].println([b]"[/b][b]后置通知[/b][b]....."[/b]);
  177.     }
  178.     [b]public void [/b]doAfterThrowing() {
  179.         System.[b][i]out[/i][/b].println([b]"[/b][b]异常通知[/b][b]...."[/b]);
  180.     }
  181.     [b]public void [/b]doAfter() {
  182.         System.[b][i]out[/i][/b].println([b]"[/b][b]最终通知[/b][b]......."[/b]);
  183.     }
  184.     [b]public [/b]Object doRound(ProceedingJoinPoint pjp) [b]throws [/b]Throwable {
  185.         [b]try [/b]{
  186.             System.[b][i]out[/i][/b].println([b]"[/b][b]环绕前置通知[/b][b]....."[/b]);
  187.             Object result = pjp.proceed();
  188.             System.[b][i]out[/i][/b].println([b]"[/b][b]环绕后置通知[/b][b]....."[/b]);
  189.             [b]return [/b]result;
  190.         } [b]catch [/b](Exception e) {
  191.             System.[b][i]out[/i][/b].println([b]"[/b][b]环绕异常通知[/b][b]......"[/b]);
  192.             [b]throw [/b]e;
  193.         } [b]finally [/b]{
  194.             System.[b][i]out[/i][/b].println([b]"[/b][b]环绕最终通知[/b][b]...."[/b]);
  195.         }
  196.     }
  197. }
  198. [/td][/tr][/table] 
  199. [size=4]7.2.3.  被代理的业务类[/size]
  200. [table][tr][td=1,1,553][b]public[/b] [b]class[/b] PersonService {//目标类
  201.  
  202. [b]public[/b] [b]void[/b] add() {
  203. System.[i]out[/i].println("PersonService.add()...");
  204. }
  205. [b]public[/b] [b]void[/b] update() {
  206. System.[i]out[/i].println("PersonService.update()...");
  207. }
  208. [b]public[/b] [b]void[/b] del() {
  209. System.[i]out[/i].println("PersonService.del()...");
  210. [b]throw new [/b]RuntimeException([b]"[/b][b]出错了[/b][b]...."[/b]);
  211. }
  212. }
  213. [/td][/tr][/table][size=4]7.2.4.  配置aop切面[/size]
  214. [table][tr][td=1,1,553]
  215.     [i]
  216.     [/i]
  217.         [i]
  218.        
  219.        
  220.        
  221.        
  222.        
  223.        
  224.         [/i]
  225.         [i]
  226.         [/i]
  227.        
  228.        
  229.        
  230.    
  231.  
  232. [/td][/tr][/table][size=4]7.2.5.  测试类[/size]
  233. [table][tr][td=1,1,553][b]public class [/b]TestXmlAop {
  234.     [b]public static void [/b]main(String[] args) {
  235.         ClassPathXmlApplicationContext context = [b]new [/b]ClassPathXmlApplicationContext([b]"applicationContext.xml"[/b]);
  236.         PersonServiceImpl personService = context.getBean(PersonServiceImpl.[b]class[/b]);
  237.         personService.add();
  238.         personService.update();
  239.         personService.del();
  240.     }
  241. }
  242. [/td][/tr][/table]开启环绕通知配置,注释前置通知、后置通知、异常通知、最终通知,进行测试
  243. [size=6]8.  Spring AOP基于Annotation实现[/size]
  244. [size=5]8.1. 基于注解方式声明切面[/size]
  245. [size=4]8.1.1.  pom依赖[/size]
  246. [code]<dependency>
  247.     <groupId>org.aspectj</groupId>
  248.     <artifactId>aspectjweaver</artifactId>
  249.     <version>1.9.7</version>
  250. </dependency>
复制代码
8.1.2.  启动@Aspect注解的支持和注解的扫描机制

applicationContext.xml配置文件用以下配置:


8.1.3.  写切面类

@Aspect声明的类,和普通类一样可以添加属性和方法,还可以包含切入点、通知、引入。
 Pointcut声明: 切入点声明包含两个部分: 
 1.签名:由一个名字和多个参数组成,必须返回void, 如:private void anyMethod(){}
 2.切入点表达式  如:@Pointcut("execution(* com.tjetc.service..*.*(..))")
@Component //把该类纳入到spring容器中管理@Aspect //代表该类是一个切面类public class AnnotationTransactionPrint {
    //声明切入点,切入点表达式(只对OrderServiceImpl这个类所有的方法进行aop
   
@Pointcut("execution(* com.tjetc.service.impl.OrderServiceImpl.*(..))")
    //切入点签名:由一个名字和多个参数组成,必须返回void
   
private void anyMethod() {
    }

    //前置通知,使用切入点签名
   
@Before("anyMethod()")
    public void doBefore() {
        System.out.println("前置通知....");
    }

    //后置通知,使用切入点签名
   
@AfterReturning("anyMethod()")
    public void doAfterReturning() {
        System.out.println("后置通知.....");
    }

    //异常通知,使用切入点签名
   
@AfterThrowing("anyMethod()")
    public void doAfterThrowing() {
        System.out.println("异常通知....");
    }

    //最终通知,使用切入点签名
   
@After("anyMethod()")
    public void doAfter() {
        System.out.println("最终通知.......");
    }

    //环绕通知,使用切入点签名
   
/*@Around("anyMethod()")*/
   
public Object doRound(ProceedingJoinPoint pjp) throws Throwable {
        try {
            System.out.println("环绕前置通知.....");
            Object result = pjp.proceed();
            System.out.println("环绕后置通知.....");
            return result;
        } catch (Exception e) {
            System.out.println("环绕异常通知......");
            throw e;
        } finally {
            System.out.println("环绕最终通知....");
        }
    }
}
 
 
8.1.4.  写一个业务类(被代理的类)

@Service //纳入spring的管理public class OrderServiceImpl {
    public void add() {
        System.out.println("PersonService.add()...");
    }
    public void update() {
        System.out.println("PersonService.update()...");
    }
    public void del() {
        System.out.println("PersonService.del()...");
        throw new RuntimeException("出错了....");
    }
}
 
8.1.5.  测试类

public class TestAnnotationAop {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        OrderServiceImpl orderService = context.getBean(OrderServiceImpl.class);
        orderService.add();
        orderService.update();
        orderService.del();
    }
}
 
 
开启环绕通知配置,注释前置通知、后置通知、异常通知、最终通知,进行测试
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

杀鸡焉用牛刀

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表