Spring 02 深入学习 IoC/AOP

13 篇文章 0 订阅
10 篇文章 0 订阅

Spring 深入学习

一、本章目标

  1. 掌握异常抛出增强、最终增强、环绕增强的使用方法
  2. 理解构造注入
  3. 掌握p命名空间注入
  4. 掌握不同数据类型的注入方法
  5. 掌握使用注解的方式实现IoC
  6. 掌握使用注解的方式实现AOP

二、Spring 增强

2.1.异常抛出增强

特点

  1. 在目标对象方法抛出异常时织入增强处理
  2. 可灵活拔插的异常处理方案

语法:

<aop:config>
	 <aop:aspect  ref="增强方法所在的Bean">
		<aop:after-throwing method="增强处理方法" pointcut-ref="切入点id"  throwing="e" />
	 </aop:aspect>
</aop:config>

实现步骤:

  1. 在maven中添加依赖包
<!--支持切入点表达式等等-->
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.9.6</version>
</dependency>
  1. 定义用于增强方法的JavaBean
/**
 * 定义包含增强方法的JavaBean
*/
public class ErrorLogger {
	private static final Logger log = Logger.getLogger(ErrorLogger.class);
	public void afterThrowing(JoinPoint jp, RuntimeException e) {
		log.error(jp.getSignature().getName() + " 方法发生异常:" + e);
	}
}
  1. 配置切面
<!-- 声明增强方法所在的Bean -->
<bean id="theErrorLogger" class="com.aiden.aop.ErrorLogger"></bean>
<!-- 配置切面 -->
<aop:config>
     <!-- 定义切入点 -->
     <aop:pointcut id="pointcut" expression="execution(* com.aiden.service.UserService.*(..))"/>
     <!-- 引用包含增强方法的Bean -->
     <aop:aspect ref="theErrorLogger">
         <!-- 将afterThrowing()方法定义为异常抛出增强并引用pointcut切入点 -->
         <!-- 通过throwing属性指定为名为e的参数注入异常实例 -->
         <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>
     </aop:aspect>
</aop:config>
  1. 在dao实现中模拟一个小错误
/**
 * 用户DAO类,实现UserDao接口,负责User类的持久化操作
*/
public class UserDaoImpl implements UserDao {
 //模拟操作数据库
 public void saveUser(User user) { 
     System.out.println("保存用户信息到数据库");
     throw new RuntimeException("为测试程序运行效果抛出的异常");
 }
}
  1. 测试
@org.junit.Test
public void testAfterThrowing() {
  ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserService service = ctx.getBean("service", UserService.class);
  User user = new User();
  user.setId(1);
  user.setUsername("aiden");
  user.setPassword("666666");
  user.setEmail("aiden@163.com");
  service.save(user);
}
  1. 运行结果

在这里插入图片描述


2.2.最终增强

特点

  • 无论方法正常运行还是抛出异常,都会在目标方法最后织入增强处理,即:该增强都会得到执行
  • Java中finally代码块的作用相似,通常用于释放资源
  • 可灵活拔插

语法:

<aop:config>
	<aop:aspect ref="增强方法所在的Bean">
		<aop:after method="增强处理方法" pointcut-ref="切入点id" />
	</aop:aspect>
</aop:config>

实现步骤

  1. 引入依赖包

  2. 定义增强的Javabean

/**
 * 定义包含增强方法的JavaBean
*/
public class AfterLogger {
	private static final Logger log = Logger.getLogger(AfterLogger.class);
	//最终增强方法
	public void afterLogger(JoinPoint jp) {
		log.info(jp.getSignature().getName() + " 方法结束执行。");
	}
}
  1. 配置切面
<!-- 声明增强方法所在的Bean -->
<bean id="theAfterLogger" class="com.aiden.aop.AfterLogger"></bean>
<!-- 配置切面 -->
<aop:config>
     <!-- 定义切入点 -->
     <aop:pointcut id="pointcut" expression="execution(* com.aiden.service.UserService.*(..))"/>
     <aop:aspect ref="theAfterLogger">
         <!-- 将afterLogger()方法定义为最终增强并引用pointcut切入点 -->
         <aop:after method="afterLogger" pointcut-ref="pointcut"/>
     </aop:aspect>
</aop:config>
  1. 测试
@org.junit.Test
public void testAfterLogger() {
  ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserService service = ctx.getBean("service", UserService.class);
  User user = new User();
  user.setId(1);
  user.setUsername("aiden");
  user.setPassword("666666");
  user.setEmail("aiden@163.com");
  service.save(user);
}
  1. 运行结果

在这里插入图片描述


2.3.环绕增强

特点

  1. 目标方法前后都可织入增强处理,可获取或修改目标方法的参数、返回值
  2. 可对目标方法进行异常处理,甚至可以决定目标方法是否执行
<aop:config>
	<aop:aspect ref="增强方法所在的Bean">
		<aop:around method="增强处理方法" pointcut-ref="切入点id" />
	</aop:aspect>
</aop:config>

实现步骤

  1. 引入依赖包,同上。

  2. 定义增强的Javabean

 /**
 * 定义包含增强方法的JavaBean
 */
public class AroundLogger {
    private static final Logger log = Logger.getLogger(AroundLogger.class);
    //环绕增强方法
    public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {
        log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName() + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
        try {
            Object result = jp.proceed();
            log.info("调用 " + jp.getTarget() + "的"+jp.getSignature().getName() +"方法。方法返回值:" + result);
            return result;
        } catch (Throwable e) {
            log.error(jp.getSignature().getName() + " 方法发生异常:" + e);
            throw e;
        } finally {
            log.info(jp.getSignature().getName() + " 方法结束执行。");
        }
    }
}

3.配置切面

<!-- 声明增强方法所在的Bean -->
 <bean id="theAfterLogger" class="com.aiden.aop.AfterLogger"></bean>
 <!-- 配置切面 -->
 <aop:config>
        <!-- 定义切入点 -->
        <aop:pointcut id="pointcut" expression="execution(* com.aiden.service.UserService.*(..))"/>
        <aop:aspect ref="theAfterLogger">
            <!-- 将afterLogger()方法定义为最终增强并引用pointcut切入点 -->
            <aop:after method="afterLogger" pointcut-ref="pointcut"/>
        </aop:aspect>
 </aop:config>

4.测试

@org.junit.Test
public void testAroundLogger() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService service = ctx.getBean("service", UserService.class);
        User user = new User();
        user.setId(1);
        user.setUsername("aiden");
        user.setPassword("666666");
        user.setEmail("aiden@163.com");
        service.save(user);
}

5.运行结果

在这里插入图片描述

三、依赖注入快速回顾

3.1.构造注入

问题:

  • 除了使用set方法,还有什么方式实现注入?

分析:

  • 可以使用带参构造
  • Spring通过构造方法为属性赋值的一种注入方式
  • 可以在对象初始化时对属性赋值,具有良好的时效性

语法:

<bean id="唯一标识" class="类的全路径">
	<constructor-arg name="参数名称" ref="依赖对象" />
</bean>

注意:

  • 编写带参构造方法后,Java虚拟机不再提供默认的无参构造方法,为了保证使用的灵活性,建议自行添加一个无参构造方法
3.2.Set 注入 (重点)

注意:被注入的属性 , 必须有set方法 , set方法的方法名由set + 属性首字母大写 , 如果属性是boolean类型 , 没有set方法 , 是 is

Address.java

package com.aiden.pojo;
/**
 * Address类
 *
 * @author Aiden
 */
public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

Student.java

package com.aiden.pojo;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * 学生信息类
 *
 * @author Aiden
 */
public class Student {
    private String name;//姓名
    private Address address;//地址
    private String[] books;//喜欢的书籍
    private List<String> hobbys;//爱好
    private Map<String, String> card;//银行卡
    private Set<String> games;//喜欢的游戏
    private String wife;
    private Properties info;

    public void setName(String name) {
        this.name = name;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public void setHobbys(List<String> hobbys) {
        this.hobbys = hobbys;
    }

    public void setCard(Map<String, String> card) {
        this.card = card;
    }

    public void setGames(Set<String> games) {
        this.games = games;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    public void show() {
        System.out.println("name=" + name
                + ",address=" + address.getAddress()
                + ",books="
        );
        for (String book : books) {
            System.out.print("<<" + book + ">>\t");
        }
        System.out.println("\n爱好:" + hobbys);

        System.out.println("card:" + card);

        System.out.println("games:" + games);

        System.out.println("wife:" + wife);

        System.out.println("info:" + info);
    }
}
3.3扩展的注入

在这里插入图片描述

3.3.1.常量注入
<bean id="student" class="com.aiden.pojo.Student">
     <property name="name" value="小明"/>
</bean>
 @Test
 public void test01(){
     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
     Student student = context.getBean("student",Student.class);
     System.out.println(student.getName());
 }
3.3.2Bean注入
 <bean id="addressObj" class="com.aiden.pojo.Address">
     <property name="address" value="长沙"/>
 </bean>
 
 <bean id="student" class="com.aiden.pojo.Student">
     <property name="name" value="小明"/>
     <!--注意点:这里的值是一个引用,ref-->
     <property name="address" ref="addressObj"/>
 </bean>
3.3.3数组注入
 <bean id="student" class="com.aiden.pojo.Student">
     <property name="name" value="小明"/>
     <property name="address" ref="addressObj"/>
     <property name="books">
         <array>
             <value>西游记</value>
             <value>红楼梦</value>
             <value>水浒传</value>
         </array>
     </property>
 </bean>
3.3.4List注入
 <property name="hobbys">
     <list>
         <value>阅读</value>
         <value>看电影</value>
         <value>听歌</value>
     </list>
 </property>
3.3.5Map注入
 <property name="card">
     <map>
         <entry key="中国农业" value="6228280128069313663"/>
         <entry key="中国建设" value="621700166000758262"/>
     </map>
 </property>	
3.3.6set注入
 <property name="games">
     <set>
         <value>LOL</value>
         <value>王者荣耀</value>
         <value>第五人格</value>
     </set>
 </property>
3.3.7Null注入
 <property name="wife"><null/></property>	
3.3.8Properties 注入
 <property name="info">
     <props>
         <prop key="学号">2021001</prop>
         <prop key="性别"></prop>
         <prop key="姓名">小明</prop>
     </props>
 </property>
3.3.9P命名和C命名注入
 public class User {
     private String name;
     private int age;
 
     public void setName(String name) {
         this.name = name;
    }
 
     public void setAge(int age) {
         this.age = age;
    }
 
     @Override
     public String toString() {
         return "User{" + "name='" + name + '\'' + ", age=" + age +'}';
     }
   }

3.3.9.1、P命名空间注入 : 需要在头文件中加入约束文件

语法:

<bean id="唯一标识" class="类的全路径" p:"属性1"="注入的值" p:"属性2"="注入的值"  />
<bean id="唯一标识" class="类的全路径" p:属性-ref="注入的Bean" />
<!--导入约束 : xmlns:p="http://www.springframework.org/schema/p"-->
<!--P(属性: properties)命名空间 , 直接注入属性-->
<bean id="user" class="com.aiden.pojo.User" p:name="张三" p:age="20"/>
 

3.3.9.2、C 命名空间注入 : 需要在头文件中加入约束文件

<!--导入约束 : xmlns:c="http://www.springframework.org/schema/c"-->
<!--C(构造: Constructor)命名空间 , 使用构造器注入-->
<bean id="user" class="com.aiden.pojo.User" c:name="张三" c:age="20"/>

四、使用注解实现Spring IoC

4.1.使用注解实现Spring IoC

注解方式将Bean的定义信息和Bean实现类结合在一起,Spring提供的注解有

@Component:实现Bean组件的定义

@Repository:用于标注DAO类

@Service:用于标注业务类

@Controller:用于标注控制器类

/**
 * 用户模块DAO业务层实现
 */
//与在XML配置文件中编写<bean id="userDao" class="dao.impl.UserDaoImpl" />等效
 @Repository("userDao")
 public class UserDaoImpl implements UserDao {}
4.2.使用注解实现Spring IoC
  • 使用 @Autowired 注解实现Bean的自动装配

  • 默认按类型匹配,可使用 @Qualifier 指定Bean的名称

  • 当dao接口有多个实现容易引发错误,可借助 @Qualifier 来区分实现

/**
 * 用户模块业务层实现
*/
@Service("userService")
public class UserServiceImpl implements UserService {
	@Autowired // 默认按类型匹配
	@Qualifier("userDao")
	private UserDao dao;
	……
}
4.3.使用注解实现Spring IoC

修改配置文件使注解生效,完成Bean的定义和组装

<?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: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:component-scan base-package="com.aiden.service,com.aiden.dao" />
</beans>

五、使用Java标准注解完成装配

5.1.使用Java标准注解完成装配2-1
  • 使用 @Resource 注解实现组件装配
  • 默认按名称匹配
@Service("userService")
public class UserServiceImpl implements UserService {
	@Resource// 查找名为dao的Bean,并注入给dao属性
	private UserDao dao;
	……
}
@Service("userService")
public class UserServiceImpl implements UserService {
	@Resource(name="userDao")// 为dao属性注入名为userDao的Bean
	private UserDao dao;
	……
}
5.2.使用Java标准注解完成装配2-2

示例:

@Service("userService")
public class UserServiceImpl implements UserService {
	@Resource(type = UserDaoImpl.class)// 用于显示指定依赖的Bean的具体类型
	private UserDao dao;
	……
}
  • 对比 @Autowired 注解和 @Resource 注解
    • @Autowired是Spring提供的注解,@Resource 是Java 提供的
    • 在不指定任何参数且不配合其他注解时,@Autowired注解会优先按Bean的类型进行装配,@Resource注解则是优先按Bean的名称进行装配

六、使用注解实现Spring AOP

6.1.使用注解实现Spring AOP

AspectJ

  • 面向切面的框架,它扩展了Java语言,定义了AOP语法,能够在编译期提供代码的织入

@AspectJ

  • AspectJ 5新增的功能,使用JDK 5.0注解技术和正规的AspectJ切点表达式语言描述切面

Spring通过集成AspectJ框架实现了以注解的方式定义切面,使得配置文件的代码大大减少

  • 利用轻量级的字节码处理框架asm处理@AspectJ中所描述的方法参数名

注意: 使用 @AspectJ ,首先要保证所用的JDK是5.0或以上版本

实现AOP的切面主要有以下几个要素

  1. 使用@Aspect注解将一个java类定义为切面
  2. 使用@Pointcut定义一个切入点,可以是一个规则表达式,比如下例中某个package下的所有函数,也可以是一个注解等
  3. 使用@Before在切入点开始处切入内
  4. 使用@After在切入点结尾处切入内
  5. 使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
  6. 使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内
  7. 使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑
6.2.使用注解实现Spring AOP

需求说明

  • 使用注解方式实现对业务方法前后增加日志

  • 使用注解定义前置增强和后置增强实现日志功能
    @Aspect
    @Before
    @AfterReturning

  • 编写Spring配置文件,完成切面织入

<aop:aspectj-autoproxy>:启用对于@AspectJ注解的支持

实现步骤

  1. 创建UserServiceLogger类使用注解定义切面
package com.aiden.aop;

import java.util.Arrays;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * 使用注解定义切面
*/
@Aspect
public class UserServiceLogger {
	private static final Logger log = Logger.getLogger(UserServiceLogger.class);

	@Pointcut("execution(* com.aiden.service.UserService.*(..))")
	public void pointcut() {}

	/**
	 * 前置增强
	 * @param jp
	 */
	@Before("pointcut()")
	public void before(JoinPoint jp) {
		log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
				+ " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
	}

	/**
	 * 后置增强
	 * @param jp
	 * @param returnValue
	 */
	@AfterReturning(pointcut = "pointcut()", returning = "returnValue")
	public void afterReturning(JoinPoint jp, Object returnValue) {
		log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
				+ " 方法。方法返回值:" + returnValue);
	}
}
  1. Dao实现
package com.aiden.dao.impl;

import org.springframework.stereotype.Repository;

import com.aiden.dao.UserDao;
import com.aiden.entity.User;

/**
 * 用户DAO类,实现UserDao接口,负责User类的持久化操作
*/
@Repository
public class UserDaoImpl implements UserDao {
	
	public int saveUser(User user) {
		// 这里并未实现完整的数据库操作,仅为说明问题
		System.out.println("保存用户信息到数据库");
		return 1;
	}
}
  1. service实现类
package com.aiden.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.aiden.service.UserService;
import com.aiden.dao.UserDao;
import com.aiden.entity.User;

/**
 * 用户业务类,实现对User功能的业务管理
*/
@Service("userService")
public class UserServiceImpl implements UserService {

	// 声明接口类型的引用,和具体实现类解耦合
 @Autowired
	private UserDao dao;

	/**
	 * 保存用户
	 * @param user
	 */
	public int save(User user) {
		// 调用用户DAO的方法保存用户信息
		return dao.saveUser(user);
	}
}
  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: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.2.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.2.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
	<!-- 注解扫描 -->
 <context:component-scan base-package="service,dao" />
	<bean class="aop.UserServiceLogger"/>
	<aop:aspectj-autoproxy />
</beans>

七、使用注解定义其他类型的增强

7.1.使用注解定义异常抛出增强

问题:

  • 使用注解来定义异常抛出增强

分析:

  • 使用@AfterThrowing注解定义异常抛出增强
/**
 * 用户DAO类,实现UserDao接口,负责User类的持久化操作
*/
@Repository
public class UserDaoImpl implements UserDao {
	public void saveUser(User user) {
		System.out.println("保存用户信息到数据库");
		throw new RuntimeException("为测试程序运行效果抛出的异常");
	}
}
/**
 * 用户业务类,实现对User功能的业务管理
*/
@Service("userService")
public class UserServiceImpl implements UserService {
	// 声明接口类型的引用,和具体实现类解耦合
	@Autowired
 private UserDao dao;
	public void save(User user) {
		// 调用用户DAO的方法保存用户信息
		dao.saveUser(user);
	}
}
package com.aiden.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;

/**
 * 通过注解实现异常抛出增强
*/
@Aspect
public class ErrorLogger {
 private static final Logger log = Logger.getLogger(ErrorLogger.class);
	
 @AfterThrowing(pointcut = "execution(* com.aiden.service.UserService.*(..))", throwing = "e")
	public void afterThrowing(JoinPoint jp, RuntimeException e) {
		log.error(jp.getSignature().getName() + " 方法发生异常:" + e);
	}
}
<?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: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.2.xsd
	http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.2.xsd
 http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
 
	<context:component-scan base-package="com.aiden.service,com.aiden.dao" />
	<bean class="com.aiden.aop.ErrorLogger"></bean>
	<aop:aspectj-autoproxy />
</beans>
7.2.使用注解定义最终增强

问题:

  • 使用注解来定义最终增强

分析:

  • 使用@After注解定义最终增强
/**
 * 用户DAO类,实现UserDao接口,负责User类的持久化操作
*/
@Repository
public class UserDaoImpl implements UserDao {
	public void saveUser(User user) {
		System.out.println("保存用户信息到数据库");
	}
}
/**
 * 用户业务类,实现对User功能的业务管理
*/
@Service("userService")
public class UserServiceImpl implements UserService {
	// 声明接口类型的引用,和具体实现类解耦合
	@Autowired
 private UserDao dao;
	public void save(User user) {
		// 调用用户DAO的方法保存用户信息
		dao.saveUser(user);
	}
}
package com.aiden.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;

/**
 * 通过注解实现最终增强
*/
@Aspect
public class AfterLogger {
	private static final Logger log = Logger.getLogger(AfterLogger.class);

	@After("execution(* com.aiden.service.UserService.*(..))")
	public void afterLogger(JoinPoint jp) {
		log.info(jp.getSignature().getName() + " 方法结束执行。");
	}
}
<context:component-scan base-package="com.aiden.service,com.aiden.dao" />
<bean class="com.aiden.aop.AfterLogger"></bean>
<aop:aspectj-autoproxy />
7.3.使用注解定义环绕增强

问题:

  • 如何使用注解来定义环绕增强?

分析:

  • 使用@Around注解定义环绕增强
package com.aiden.aop;

import java.util.Arrays;
import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;

/**
 * 通过注解实现环绕增强
*/
@Aspect
public class AroundLogger {
	private static final Logger log = Logger.getLogger(AroundLogger.class);

	@Around("execution(* com.aiden.service.UserService.*(..))")
	public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {
		log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
				+ " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
		try {
			Object result = jp.proceed();
			log.info("调用 " + jp.getTarget() + " 的 "
					+ jp.getSignature().getName() + " 方法。方法返回值:" + result);
			return result;
		} catch (Throwable e) {
			log.error(jp.getSignature().getName() + " 方法发生异常:" + e);
			throw e;
		} finally {
		    log.info(jp.getSignature().getName() + " 方法结束执行。");
		}
	}
}
<context:component-scan base-package="com.aiden.service,com.aiden.dao" />
<bean class="com.aiden.aop.AroundLogger"></bean>
<aop:aspectj-autoproxy />
7.4.注解使用小结

Spring在同一个功能上提供了注解和配置文件两种实现方式以供选择
通常情况下,优先选择注解来简化配置工作量
常用的注解
@AfterThrowing
@Before
@AfterReturning
@Around
@After
@Aspect
@Pointcut

八、本章总结

在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

众生云海,一念初见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值