相关实例:
使用特定接口定义切面类
使用注解定义切面类
上述切面类,要么用到了特定接口,要么用到了注解,各有不足之处。使用注解有个问题,就是直接在类里面编写注解,不能分离,不方便修改与维护
其实还有一种方法,既不需要实现特定接口,也不需要使用注解,只需在第三方的配置文件中配置一下,这就是使用XML配置文件定义切面的方式,也是目前最常用的AOP方式。
1.若干AspectJ标签的含义
<aop:config>:配置AOP,实现将一个普通类设置为切面类的功能
<aop:aspect>:配置切面
<aop:pointcut>:配置切点
<aop:before>:配置前置通知,将一个切面方法设置为前置增强
<aop:after-returning>:配置后置通知,将一个切面方法设置为后置通知,有返回值
<aop:around>:配置环绕通知
<aop:after-throwing>:配置异常通知,将一个切面设置为异常抛出增强
<aop:after>:配置最终通知,将一个切面方法设置为后置增强,没有有返回值,无论是否异常都执行
2.定义切点的常用方法(即表达式)
execution(public * *(...)):指定切点为任意公共方法
execution(* save *(...)):指定切点为任何一个以 save 开始的方法
execution(* com.xiaochen.service.*.*(...)):指定切点为定义在service包中的任意类的任意方法
execution(* *.service.*.doUpdate()):指定只有一级包下的service子包下的所有类中的doUpdate()方法为切点
execution(* *..service.*.doUpdate()):指定所有service子包下的所有类中的doUpdate()方法为切点
execution(* com.xiaochen.service.UserService.*(...)):指定切点为UserService类中的任意方法
execution(* com.xiaochen.service.UserService+.*(...)):指定切点:UserSrvice若为接口,则为接口中的及其所有实现类中的任意方法,
UserSrvice若为类,则为该类及其子类中的任意方法
execution(* doRegister(String,*)):指定切点为:所有doRegister()方法,该方法的第一个参数为String,第二个参数为任意类型。
应用实例:通过XML配置的方式定义一个切面类
项目目录结构图
IUserDao.java
package com.xiaochen.dao;
public interface IUserDao {
public void addUser();
}
UserDaoImpl.java
package com.xiaochen.dao;
import org.springframework.stereotype.Component;
//使用注解方式定义一个Bean,其id为userDao
@Component("userDao")
public class UserDaoImpl implements IUserDao{
@Override
public void addUser() {
System.out.println("新增一个用户到数据库中");
}
}
UserService.java
package com.xiaochen.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import com.xiaochen.dao.IUserDao;
//使用注解方式定义Bean,其id为userService
@Component("userService")
public class UserService {
//使用注解注入在UserDaoImpl定义好的Bean
@Resource(name="userDao")
private IUserDao userDao;
//给域属性赋值
public void setUserDao(IUserDao userDao) {
this.userDao=userDao;
}
//调用IUserDao的addUser()方法
public void addUser() {
userDao.addUser();
}
}
Test.java
package com.xiaochen.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.xiaochen.service.UserService;
public class Test {
public static void main(String[] args) {
//1.加载配置文件
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//2.从配置文件中获取Bean
UserService userService=(UserService)context.getBean("userService");
//3.使用Bean
userService.addUser();
}
}
MyLog.java
package com.xiaochen.aop;
import com.sun.istack.internal.logging.Logger;
//该类既不实现特定接口,也不加注解
public class MyLog {
private static final Logger log=Logger.getLogger(MyLog.class);
public void beforeMethod() {
log.info("使用XML配置定义切面,开始执行方法。。。");
}
public void afterMethod() {
log.info("使用XML配置定义切面,完成执行方法。。。");
}
}
applicationContext.xml
<?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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置组件扫描器,在指定的基本包中扫描注解 -->
<context:component-scan base-package="com.xiaochen" />
<!-- 定义切面类 -->
<!-- 为添加注解的myLog类创建一个Bean -->
<bean id="myLog" class="com.xiaochen.aop.MyLog" />
<aop:config>
<!-- 定义切点 -->
<aop:pointcut expression="execution(* com.xiaochen.service.*.*(..))" id="pointcut" />
<!-- 引用切面类,设置各种通知 -->
<aop:aspect ref="myLog">
<!-- 将切面类中的beforeMethod方法设置为前置通知 -->
<aop:before method="beforeMethod" pointcut-ref="pointcut"></aop:before>
<!-- 将切面类中的afterMethod方法设置为后置通知,有返回值 -->
<aop:after-returning method="afterMethod" pointcut-ref="pointcut"></aop:after-returning>
</aop:aspect>
</aop:config>
</beans>
log4j.properties
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.xiaochen=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
运行结果图
版权声明:本文为weixin_45873215原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。