@Repository
@Scope("prototype")
public class UserDao implements IUserDao {
public void save(){
System.out.println("保存成功,无返回值");
}
}
@Configuration
@ComponentScan("com.liaoxiang")
//默认使用的JDK动态代理
@EnableAspectJAutoProxy()
public class AppConfig {
}
@Component
@Aspect
//@Scope("prototype")
public class Advice {
/**
* execution
* dao包下的所有方法都增强
*/
@Pointcut("execution(* com.liaoxiang.dao.impl.*.*(..))")
public void pointCutExecution1 (){}
/**
* 增强方法
*/
@Before("pointCutExecution1()")
public void before(){
System.out.println("增强方法执行,当前切面:"+this.hashCode());
}
}
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
IUserDao dao1 = (IUserDao)ac.getBean("userDao");
IUserDao dao2 = (IUserDao)ac.getBean("userDao");
System.out.println("dao1: "+dao1.hashCode());
System.out.println("dao2: "+dao2.hashCode());
dao1.save();
dao2.save();
}
}
执行结果:
dao1: 1279584786
dao2: -1597778003
增强方法执行,当前切面:1620890840
保存成功,无返回值
增强方法执行,当前切面:1620890840
保存成功,无返回值
当我们想要对某个类的某些方法进行增强的时候,而这类如果是多例的,上面的配置使用的切面却是单例的,如果要使切面也是多例的,则在使用JDK动态代理的情况下,需要作如下的配置
@Component
@Aspect("perthis(target(com.liaoxiang.dao.impl.UserDao))")
public class Advice {
/**
* execution
* dao包下的所有方法都增强
*/
@Pointcut("execution(* com.liaoxiang.dao.impl.*.*(..))")
public void pointCutExecution1 (){}
/**
* 增强方法
*/
@Before("pointCutExecution1()")
public void before(){
System.out.println("增强方法执行,当前切面:"+this.hashCode());
}
}
再次执行测试方法
dao1: -1527878935
dao2: -827515386
增强方法执行,当前切面:1648001170
保存成功,无返回值
增强方法执行,当前切面:169663597
保存成功,无返回值
注意:在使用默认JDK动态代理的时候,配置切面的时候不能使用this
:
@Aspect("perthis(this(com.liaoxiang.dao.impl.UserDao))")
如果使用的是CGLIB动态代理,@EnableAspectJAutoProxy(proxyTargetClass = true)
,则二者皆可。