默认情况下,在Spring AOP里面的切面类是单例模式(Singleton),也就是说我们声明的Aspect类只能实例化一个对象出来使用。但是假设我们使用的切面类里面有公共对象或者变量需要操作,或者应用于多线程环境,单例模式的切面类显然就不能满足我们的要求了。那么我们应该怎么做才能给每一个切面都创建一个单独的实例呢?
Aspect Instantiation Models
这一章节的直接翻译就是切面实例化模型,首先还是看看官网怎么说的,以下引用来自官网:
By default, there is a single instance of each aspect within the application context. AspectJ calls this the singleton instantiation model. It is possible to define aspects with alternate lifecycles. Spring supports AspectJ’s perthis and pertarget instantiation models ( percflow, percflowbelow, and pertypewithin are not currently supported).
先看看我们的例子
有前面的基础这个地方我们就直接写关键代码了
@Aspect("perthis(com.wfg.aop2.IndexAspect.pointCut())")
@Component
@Scope("prototype")
public class IndexAspect {
@DeclareParents(value = "com.wfg.aop2.dao.*+",defaultImpl = IndexPlusDaoImpl.class)
private static IndexDao indexDao;
@Pointcut("this(com.wfg.aop2.dao.IndexDaoImpl)")
public void pointCut(){
}
@Before("com.wfg.aop2.IndexAspect.pointCut()")
public void pointCutBefore(){
System.out.println(this.hashCode());
System.out.println("before==============");
}
@Service
@Scope("prototype")
public class IndexDaoImpl implements IndexDao {
@Override
public void saveUser(String user) {
System.out.println("save user" + user);
}
}
@Scope(“prototype”) 修改成prototype类型的
public class Test2 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
IndexDao bean = context.getBean(IndexDao.class);
// System.out.println("类名称:"+bean.getClass().getName());
// System.out.println("bean instanceof IndexDao :"+(bean instanceof IndexDao));
// System.out.println("bean instanceof IndexDaoImpl :"+(bean instanceof IndexDaoImpl));
// System.out.println("bean instanceof Proxy :"+(bean instanceof Proxy));
bean.saveUser("zhangsan");
IndexDao bean2 = context.getBean(IndexDao.class);
bean2.saveUser("zhangsa44444n");
bean.saveUser("zhang55555san");
IndexPlusDao dao = (IndexPlusDao) context.getBean(IndexPlusDaoImpl.class);
dao.Query();
}
}
测试hascode值这个时候发现是不想等的
pethis和pertarget区别就是this和target的区别
this表示 代理对象
target表示源对象 即被代理对象