一、搭建环境

环境搭建同学习笔记day08

二、使用spring主配置文件的方式进行注解配置

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:aop="http://www.springframework.org/schema/aop"
        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/aop 
        					http://www.springframework.org/schema/aop/spring-aop.xsd
        					http://www.springframework.org/schema/context
        					http://www.springframework.org/schema/context/spring-context.xsd"> 
	
	<!-- 配置要扫描的包 -->
	<context:component-scan base-package="cn.itcast"></context:component-scan>
	
	<!-- 开启spring注解AOP的支持 ,如果不写,就不支持spring的aop-->
	<aop:aspectj-autoproxy/>
	
</beans>
2、通知配置
package cn.itcast.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 记录日志的工具类
 * @author wingzhe
 *
 */
@Component("logger")
@Aspect
public class Logger {
	
	/**
	 * 前置通知
	 */
	//@Before("execution(* cn..*.*(..))")
	public void beforePrintLog(){
		System.out.println("Logger类中的beforePrintLog方法开始记录日志了");
	}
	
	/**
	 * 后置通知
	 */
	//@AfterReturning("execution(* cn..*.*(..))")
	public void afterReturningPrintLog(){
		System.out.println("Logger类中的afterReturningPrintLog方法开始记录日志了");
	}
	
	
	/**
	 * 异常通知
	 */
	//@AfterThrowing("execution(* cn..*.*(..))")
	public void afterThrowingPrintLog(){
		System.out.println("Logger类中的afterThrowingPrintLog方法开始记录日志了");
	}
	
	
	/**
	 * 最终通知
	 */
	//@After("execution(* cn..*.*(..))")
	public void afterPrintLog(){
		System.out.println("Logger类中的afterPrintLog方法开始记录日志了");
	}
	
	
	/**
	 * 环绕通知
	 * 问题:
	 * 	当我们配置了环绕通知,发现运行时,通知里面的代码执行了。而业务核心方法的代码没有执行。
	 * 分析:
	 * 	通过动态代理,我们得知环绕通知是指的整个invoke方法,里面明确的调用业务核心方法。
	 *  在我们配置的环绕通知中,没有明确的调用业务核心方法。
	 *  所以,才会只有环绕通知的代码执行,而service中的方法没有执行
	 * 解决:
	 * 	spring框架给我们提供了一个接口,ProceedingJoinPoint,该接口可以作为环绕通知方法的参数。
	 * 	在程序运行期间,spring框架会为我们提供该接口的实现类。
	 * 	该接口中有一个方法:proceed();此方法就相当于明确的调用了业务核心方法
	 * 
	 * 环绕通知:
	 * 	它不是用于指定增强代码何时执行的,而是spring框架为我们提供的一种在代码中手动控制增强方法何时执行的方式。
	 */
	@Around("pt1()")//此处要带()
	public void aroundPringLog(ProceedingJoinPoint pjp){
		try {
			System.out.println("前:Logger类中的aroundPringLog方法开始记录日志了");
			pjp.proceed();//相当于调用service的方法(执行了业务层的核心方法)
			System.out.println("后:Logger类中的aroundPringLog方法开始记录日志了");
		} catch (Throwable e) {
			System.out.println("异:Logger类中的aroundPringLog方法开始记录日志了");
			e.printStackTrace();
		}finally{
			System.out.println("终:Logger类中的aroundPringLog方法开始记录日志了");
		}
	}
	
	@Pointcut("execution(* cn..*.*(..))")
	private void pt1(){}
}
3、测试类
package cn.itcast.ui;

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

import cn.itcast.service.ICustomerService;

public class Client {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
		ICustomerService customerService = (ICustomerService)ac.getBean("customerService");
		customerService.saveCustomer();
	}

}

三、不使用spring主配置文件的方式进行注解配置

1、编写配置文件类
package cn.itcast.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("cn.itcast")
@EnableAspectJAutoProxy //开启对aop的支持
public class SpringConfiguration {

}
2、编写测试类
package cn.itcast.ui;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.itcast.config.SpringConfiguration;
import cn.itcast.service.ICustomerService;

public class Client {

	public static void main(String[] args) {
		ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
		ICustomerService customerService = (ICustomerService)ac.getBean("customerService");
		customerService.saveCustomer();
	}

}