Spring框架

一、概述

  1. Spring是轻量级的开源的JavaEE框架。
  2. Spring可以解决企业应用开发的复杂性
  3. Spring有两个核心的部分:IOC 和 AOP
  • IOC:控制反转,把创建对象过程交给Spring进行管理
  • AOP:面向切面,不修改源代码进行功能管理

Spring特点:

  1. 方便解耦,简化开发
  2. AOP编程支持
  3. 方便程序测试
  4. 方便和其他框架进行整合
  5. 方便进行事务操作
  6. 降低API开发难度

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

案例1

1 创建spring的核心配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans 	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	<!-- xsd文件对当前xml文件进行语法检查 :规定有哪些标签 有哪些属性 标签的嵌套关系-->
	
</beans>

2 创建实体类

public class Student {
    private Integer sid;
    private String sname;
    private String sex;
    private Integer sage;
    private Boolean sdy;
    ...
}

3 在核心配置文件中通过bean标签来创建对象

<!-- 通过bean标签创建程序依赖的对象 -->
<!-- Integer sid, String sname, String sex, Integer sage, Boolean sdy -->
<bean name="s1" class="com.zhiyou.ioc.Student">
    <property name="sid"  value="1001"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
</bean>
<bean name="s2" class="com.zhiyou.ioc.Student">
    <constructor-arg  index="0"  value="1002" />
    <constructor-arg  index="2"  value="韩红" />
    <constructor-arg  index="1"  value="女" />
    <constructor-arg  index="4"  value="false" />
    <constructor-arg  index="3"  value="33" />
</bean>

4 测试类

//创建spring上下文对象  关联核心配置文件
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("com/zhiyou/ioc/spring1.xml");
//通过上下文对象的getbean方法 由bean的name值获取javabean对象
Student stu1=(Student)context.getBean("s1");
System.out.println(stu1);
Student stu2=(Student)context.getBean("s2");
System.out.println(stu2);
context.close();

 二、IOC容器

  1. IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
  2. Spring提供IOC容器实现的两种方式:(两个接口)
  1. BeanFactory,IOC容器基本实现,是Spring内部使用接口,不提供给开发人员进行使用

      *加载配置文件时不会创建对象,在获取对象时才创建对象

     2.APPlicationContext ,BeanFactory的子接口,提供更多强大的功能,一般由开发人员使用

        *加载配置文件时就会把在配置文件对象进行创建

3、APPlicationContext接口的实现类

1)FileSystemXmAPPlicationContext     2)ClassPathXmAPPlicationContext

写路径时如果是FileSystemXmAPPlicationContext则写盘符所在路径

写路径时如果是ClassPathXmAPPlicationContext 则写src 下的路径

1、xml配置方式创建对象

<bean id="stu" class="com.zhiyou.ioc.Student"></bean>

2、xml方式注入属性

1) set方式注入属性

前提:实体类必须有set方法

property标签    name为属性的名字  value为属性的值

<bean name="s1" class="com.zhiyou.ioc.Student">
    <property name="sid"  value="1001"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
</bean>

2)构造方法的方式注入属性

ioc创建对象时,会默认使用实体类中的无参构造方法

用构造方法赋值时,需要声明有参的构造方法

<bean name="s2" class="com.zhiyou100.ioc.Student">
    <constructor-arg  name="sid"  value="1002" />
    <constructor-arg  name="sname"  value="韩红" />
    <constructor-arg  name="sex"  value="女" />
    <constructor-arg  name="sdy"  value="false" />
    <constructor-arg  name="sage"  value="33" />
</bean>

3、注入其他类型的属性

1)null值

<property name="address">
     <null/>
</property>

2)对象类型

用ref引入另一个bean

<bean name="s1" class="com.zhiyou.ioc.Student">
    <property name="sid"  value="1001"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
    <!-- 给teacher属性赋值:private Teacher  teacher -->
    <!-- property和constructor-arg标签的value属性:给单值数据(基本数据类型+字符串)赋值 -->
    <!-- property和constructor-arg标签的ref属性:给引用类型数据(对象类型)赋值 -->
    <property name="teacher" ref="t1"/>
</bean>

<bean name="t1" class="com.zhiyou.ioc.Teacher">
    <property name="tid"  value="1"/>
    <property name="tname"  value="张老师"/>
    <property name="tsex"  value="男"/>
</bean>

3)数组和集合类型属性

<bean name="tea1" class="com.zhiyou.ioc.Teacher">
    <property name="tid" value="11"/>
    <property name="tname" value="高老师"/>
    <property name="tsex" value="男"/>
</bean>
<bean name="tea2" class="com.zhiyou.ioc.Teacher">
    <property name="tid" value="12"/>
    <property name="tname" value="田老师"/>
    <property name="tsex" value="男"/>
</bean>
<bean name="tea3" class="com.zhiyou.ioc.Teacher">
    <property name="tid" value="13"/>
    <property name="tname" value="陈老师"/>
    <property name="tsex" value="女"/>
</bean>

<bean name="w1" class="com.zhiyou.ioc.Worker">
    <!-- 	     	 private Integer wid; -->
    <property name="wid" value="1001"/>
    <!-- 			 private Teacher teacher; -->
    <property name="teacher" ref="tea1"/>
    <!-- 			 private int[] arrInt; -->
    <property name="arrInt">
        <array value-type="int">
            <value>111</value>
            <value>112</value>
            <value>113</value>
            <value>114</value>
        </array>
    </property>

    <!-- 			 private Teacher[] arrTea; -->
    <property name="arrTea">
        <array value-type="com.zhiyou.ioc.Teacher">
            <ref bean="tea1"/>
            <ref bean="tea2"/>
            <ref bean="tea3"/>
        </array>
    </property>

    <!-- 			 private List<Teacher> listTea; -->
    <property name="listTea">
        <list value-type="com.zhiyou.ioc.Teacher">
            <ref bean="tea1"/>
            <ref bean="tea2"/>
            <ref bean="tea3"/>
            <ref bean="tea1"/>
            <ref bean="tea2"/>
            <ref bean="tea3"/>
        </list>
    </property>

    <!-- 			 private List<Integer> listInt; -->
    <property name="listInt">
        <list value-type="java.lang.Integer">
            <value>21</value>
            <value>31</value>
            <value>41</value>
        </list>
    </property>

 <!-- 			 private Set<Integer> setInt; -->
    <property name="setInt">
        <set value-type="java.lang.Integer">
            <value>22</value>
            <value>32</value>
            <value>42</value>
            <value>22</value>
            <value>32</value>
            <value>42</value>
        </set>
    </property>

    <!-- 			 private Map<String, Teacher> map; -->
    <property name="map">
        <map key-type="java.lang.String" value-type="com.zhiyou.ioc.Teacher">
            <entry key="key1" value-ref="tea1"/>
            <entry key="key2" value-ref="tea2"/>
            <entry key="key3" value-ref="tea3"/>
        </map>
    </property>
</bean>

4、bean的作用域

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

<bean name="s2" class="com.zhiyou.ioc.Student" scope="prototype">
    <property name="sid"  value="1001"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
</bean>

作用域

描述

单例(singleton)

(默认)每一个Spring IoC容器都拥有唯一的一个实例对象

原型(prototype)

一个Bean定义,任意多个对象

请求(request)

一个HTTP请求会产生一个Bean对象,也就是说,每一个HTTP请求都有自己的Bean实例。只在基于web的Spring ApplicationContext中可用

会话(session)

限定一个Bean的作用域为HTTPsession的生命周期。同样,只有基于web的Spring ApplicationContext才能使用

全局会话(global session)

限定一个Bean的作用域为全局HTTPSession的生命周期。通常用于门户网站场景,同样,只有基于web的Spring ApplicationContext可用

5、bean的懒加载

 bean的懒加载:默认情况下scope=singleton的bean 项目启动spring容器加载核心配置文件就会创建bean对应的对象 
      开头通过lazy-init="true"属性来指定 bean标签第一次被调用时才创建对象

<bean name="s3" class="com.zhiyou.ioc.Student" scope="singleton" lazy-init="true">
    <property name="sid"  value="1003"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
</bean>

6、bean的生命周期

生命周期:从对象创建到对象销毁的过程

(1)通过构造器创建 bean 实例(无参数构造)

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

(3)调用 bean 的初始化的方法(需要进行配置初始化的方法)

(4)bean 可以使用了(对象获取到了)

(5)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

其中初始化和销毁方法需要自定义,并且在配置文件中配置,用bean标签中属性指定

7、属性的自动装配(自动关联的属性赋值)

autowire="byName":自动给对象类型的属性赋值:bean名字和属性名一致

<bean name="s2" class="com.zhiyou.ioc.Student" autowire="byName">
    <property name="sid"  value="1003"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
    <!-- private Teacher teacher; -->
</bean>

  autowire="byType":如果找到一个指定类型的bean 直接赋值
  如果找到多个 赋值bean的名字与属性名相同的
  如果找到多个 但没有bean的名字与属性名字相同的  报错:UnsatisfiedDependencyException

<bean name="s3" class="com.zhiyou.ioc.Student" autowire="byType">
    <property name="sid"  value="1003"/>
    <property name="sex"  value="男"/>
    <property name="sname"  value="韩梅梅"/>
    <property name="sage"  value="23"/>
    <property name="sdy"  value="true"/>
    <!-- private Teacher teacher; -->
</bean>

8、注解形式的ioc

Spring 创建对象提供注解

(1)@Component

(2)@Service

(3)@Controller

(4)@Repository

Spring 属性注入提供注解 

(1)@Autowired:根据属性类型进行自动装配

(2)@Qualifier:根据名称进行注入,要和@Autowired一起使用

(3)@Resource:可以根据类型注入,也可以根据名称注入

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

1)在核心配置文件中引入context的命名空间和xsd

<beans 	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <!--命名空间和xsd文件都是复制修改的-->
</beans>

2)使用context标签指定添加了注解的实体类的位置

<!-- 添加标签指定添加注解的实体类位置 -->
<context:component-scan base-package="com.zhiyou.ioc"/>

3)在实体类上添加注解

//@Repository    //创建bean的注解:给dao持久层的类添加的注解
//@Controller    //创建bean的注解:给controller控制层的类添加的注解
//@Service       //创建bean的注解:给service业务层的类添加的注解
@Component("s2")  //创建bean的注解:不确定当前bean具体属于那一层  可以加属性:用于指定bean的名字  不加默认是类名首字母小写
//@Scope("prototype") //指定bean的作用域
@Lazy//懒加载  只适用于单例模式
public class Student {
    {
        System.out.println("构造代码块!!");
    }
    //@Value("1001")给属性赋值:可以加载属性上  也可以加在set方法上
    @Value("1001")
    private Integer sid;
    @Value("韩庚")
    private String sname;
    @Value("男")
    private String sex;
    @Value("19")
    private Integer sage;
    private Boolean sdy;

    //@Autowired  //自动装配:策略和byType类似
    //@Resource(name="teacher")//自动装配:name指定bean的名字
    @Resource
    private Teacher teacher;
    public Teacher getTeacher() {
        return teacher;
    }
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
    public Integer getSid() {
        return sid;
    }
    public void setSid(Integer sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Integer getSage() {
        return sage;
    }
    public void setSage(Integer sage) {
        this.sage = sage;
    }
    public Boolean getSdy() {
        return sdy;
    }
    @Value("true")
    public void setSdy(Boolean sdy) {
        this.sdy = sdy;
    }	
    @Override
    public String toString() {
        return "Student [sid=" + sid + ", sname=" + sname + ", sex=" + sex + ", sage=" + sage + ", sdy=" + sdy
            + ", teacher=" + teacher + "]";
    }
    public Student(Integer sid, String sname, String sex, Integer sage, Boolean sdy) {
        super();
        this.sid = sid;
        this.sname = sname;
        this.sex = sex;
        this.sage = sage;
        this.sdy = sdy;
    }
    public Student() {
        super();
    }

    @PostConstruct
    public void initMethod(){
        System.out.println("public void initMethod()");
    }
    @PreDestroy
    public void destroyMethod(){
        System.out.println("public void destroyMethod()");
    }
}

4)@Resource和@Autowired的区别

其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource

@Resource默认按照ByName方式注入,有nametype两个属性,分别是按照名称和按照类型注入,如果这两个属性都没有指定就会按默认方式注入,也可以两个同时指定

@Autowired默认按照ByType方式注入,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果想要按照ByName方式需要配合@Qualifier注解一起使用,指定@Qualifiervalue属性值为要注入的bean的名字

三、AOP容器

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

(2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能

1、aop术语

(1)连接点:类里面哪些方法可以被增强,这些方法成为连接点

(2)切入点:实际被真正增强的方法,成为切入点

(3)通知(增强):实际增强的逻辑部分称为通知(增强)

     通知的类型:*前置通知 *后置通知 *环绕通知 *异常通知 *最终通知

(4)切面(是动作):把通知应用到切入点的过程

2、切入点表达式

(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强

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

*代表全部

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

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

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

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

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

execution(* com.zhiyou.dao.*.* (..))

3、通知类型

@Before注解表示作为前置通知

@After注解表示作为最终通知

@AfterReturning注解表示作为后置通知

@AfterThrowing注解表示作为异常通知

@Around注解表示作为环绕通知

注意:After与AfterReturning的区别:

After无论如何都执行,也称为最终通知

AfterReturning发生异常时不执行,称为后置通知或返回通知

4、基于xml配置方式的aop

1)导入jar包

 2)创建目标实体类定义方法,并抽取接口

public class Student implements Serializable, StudentInterface{
	private String sname;

	public int addHao(int a,int b){
		System.out.println("学生'"+sname+"'正在算术:"+a+"+"+b+"="+(a+b));
		return a+b;
	}
	public void eatHao(String food){
		System.out.println("学生'"+sname+"'正在吃饭:'"+food+"'真香!");
	}
	public void smokeCha(String name){
		System.out.println("学生'"+sname+"'正在吸烟:'"+name+"'吞云吐雾!");
	}
	public void sleepHao(){
		System.out.println("学生'"+sname+"'正在休息:劳逸结合!");
	}
	public void gameCha(String gname){
		System.out.println("学生'"+sname+"'正在玩游戏:玩物丧志!");
	}
    ....
}

3)创建代理实体类,配置通知方法

//创建实体类 封装所有的辅助功能
public class MyAdvice {
	public void after1AdviceMethod(){
		System.out.println("..........after1AdviceMethod111111111");
	}
	public void after2AdviceMethod(){
		System.out.println("..........after2AdviceMethod222222222");
	}
	public void beforeAdviceMethod(){
		System.out.println("beforeAdviceMethod..................");
	}
	public void exceptionAdviceMethod(Exception e){
		System.out.println("exceptionAdviceMethod................."+e);
	}
	public Object aroundAdviceMethod(ProceedingJoinPoint pjp){
		System.out.println("around-----------1");
		Object result=null;
		try {
			result=pjp.proceed();
		} catch (Throwable e) {
			throw new RuntimeException(e);
		}
		System.out.println("around-----------2");
		return result;
	}
}

4) 在核心配置文件中声明:context和aop的命名空间和xsd

<beans 	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">

5)创建目标bean和代理bean

<!-- 2创建bean:目标bean -->
<bean name="stu" class="com.zhiyou.Student">
    <property name="sname"  value="韩梅梅" />
</bean>
<bean name="stu2" class="com.zhiyou.Student">
    <property name="sname"  value="韩红" />
</bean>
<!-- 3创建bean:通知bean -->
<bean name="advice" class="com.zhiyou.MyAdvice"/>

6) 通过aop标签实现织入

<!-- 4 通过aop标签把通知添加到目的对象  织入 -->
                                           
<aop:config>
    <aop:aspect ref="advice"><!-- 声明通知bean -->
        <aop:pointcut id="myCut1" expression="execution(* com.zhiyou.*.*Hao(..))" /><!-- 指定切入点 -->
        <aop:before method="beforeAdviceMethod" pointcut-ref="myCut1" />
        <aop:after method="after1AdviceMethod" pointcut-ref="myCut1" />
        <aop:after-returning method="after2AdviceMethod" pointcut-ref="myCut1" />
        <aop:after-throwing method="exceptionAdviceMethod" pointcut-ref="myCut1" throwing="e"/>
    </aop:aspect>
</aop:config>

<aop:config>
    <aop:aspect ref="advice"><!-- 声明通知bean -->
        <aop:pointcut id="myCut2" expression="execution(* com.zhiyou.*.*Cha(..))" /><!-- 指定切入点 -->
        <aop:around method="aroundAdviceMethod" pointcut-ref="myCut2" />
        <aop:after-throwing method="exceptionAdviceMethod" pointcut-ref="myCut1" throwing="e"/>
    </aop:aspect>
</aop:config>

7)测试

//		//创建spring上下文对象  关联核心配置文件
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("com/zhiyou/spring.xml");
StudentInterface studentProxy=(StudentInterface)context.getBean("stu2");
studentProxy.eatHao("黄焖鸡");
System.out.println();
studentProxy.gameCha("CS");
System.out.println();
studentProxy=(StudentInterface)context.getBean("stu");
studentProxy.eatHao("黄焖鸡");
System.out.println();
studentProxy.gameCha("CS");
context.close();

4、基于注解方式aop

增强类也就是代理类要用@AspectJ注解

1)创建核心配置文件引入context和aop的命名空间和xsd文件

<beans 	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">

2)在核心配置文件通过context标签指定扫描的实体类包

<!-- 2通过context标签component-scan:指定扫描的实体类包  为添加注解的实体类创建bean  -->
<context:component-scan base-package="com.zhiyou"/>

3)创建封装目标实体类并抽取接口

@Component
public class Teacher implements Serializable, TeacherInterface{
	@Value("1")
	private Integer tid;
	@Value("张老师")
	private String tname;
	@Value("3000")
	private Float tsalary;
    public void eatHao(String food){
		System.out.println("老师'"+tname+"'正在吃饭:'"+food+"'真香!");
	}
	public int teachHao(int a){
		System.out.println("老师'"+tname+"'正在授课::求"+a+"的三次方");
		//System.out.println(1/0);
		return (int)Math.pow(a, 3);
	}
	
	public void smokeCha(String name){
		System.out.println("老师'"+tname+"'正在吸烟:'"+name+"'吞云吐雾,注意身体!");
	}
    ...
}
//创建主流业务的实体类
@Component
public class Student implements Serializable, StudentInterface{
	@Value("韩梅梅")
	private String sname;
	@Value("1001")
	private Integer sid;
	@Value("99")
	private Float score;
	@Autowired
	private TeacherInterface teacher;
    	public int addHao(int a,int b){
		System.out.println("学生'"+sname+"'正在算术:"+a+"+"+b+"="+(a+b));
		return a+b;
	}
	public void eatHao(String food){
		System.out.println("学生'"+sname+"'正在吃饭:'"+food+"'真香!");
	}
	public void smokeCha(String name){
		System.out.println("学生'"+sname+"'正在吸烟:'"+name+"'吞云吐雾!");
	}
	public void sleepHao(){
		System.out.println("学生'"+sname+"'正在休息:劳逸结合!");
	}
	public void gameCha(String gname){
		System.out.println("学生'"+sname+"'正在玩游戏:玩物丧志!");
		
		return;
	}
    ...
}

4)创建增强实体类,并配置通知

@Component
@Aspect  //指定当前bean是通知bean
public class MyAdvice {
	 //通过注解@Pointcut定义切入点
	 @Pointcut("execution(* com.zhiyou100.day05.*.*Hao(..))")
	 public void haoPointCut() {}//方法名 即为切入点的id
	 //通过注解@Pointcut定义切入点
	 @Pointcut("execution(* com.zhiyou100.day05.*.*Cha(..))")
	 public void chaPointCut() {}//方法名 即为切入点的id
	 //通过注解@Pointcut定义切入点
	 @Pointcut("execution(* com.zhiyou100.day05.*.*(..))")
	 public void allPointCut() {}//方法名 即为切入点的id
	
	//@After(value="execution(* com.zhiyou100.day05.*.*Hao(..))")
	@After(value="haoPointCut()")
	public void after1AdviceMethod(JoinPoint jp){
		System.out.println("..........after1AdviceMethod111111111::"+jp.getSignature().getName());
	}
	
	
	//@AfterReturning(value="execution(* com.zhiyou100.day05.*.*Hao(..))",returning="result")
	@AfterReturning(value="haoPointCut()",returning="result")
	public void after2ReturningAdviceMethod(Object result){
		System.out.println("..........after2AdviceMethod222222222:::返回值是"+result);
	}
	
	//@Before(value="execution(* com.zhiyou100.day05.*.*Hao(..))")
	@Before(value="haoPointCut()")
	public void beforeAdviceMethod(JoinPoint jp){
		System.out.println("beforeAdviceMethod.................:::"+jp.getSignature().getName());
	}
	
	@AfterThrowing(value="allPointCut()",throwing="e")
	//@AfterThrowing(value="execution(* com.zhiyou100.day05.*.*(..))",throwing="e")
	public void exceptionAdviceMethod(Exception e){
		System.out.println("exceptionAdviceMethod................."+e);
	}
	
	//@Around(value="execution(* com.zhiyou100.day05.*.*Cha(..))")
	@Around(value="chaPointCut()")
	public Object aroundAdviceMethod(ProceedingJoinPoint pjp){
		System.out.println("around-----------1");
		Object result=null;
		try {
			result=pjp.proceed();
		} catch (Throwable e) {
			throw new RuntimeException(e);
		}
		System.out.println("around-----------2");
		return result;
	}  
}


版权声明:本文为weixin_45943192原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。