AbstractAdvisorAutoProxyCreator.java
上传用户:jiancairen
上传日期:2007-08-27
资源大小:26458k
文件大小:5k
源码类别:

Java编程

开发平台:

Java

  1. /*
  2.  * Copyright 2002-2004 the original author or authors.
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */ 
  16. package org.springframework.aop.framework.autoproxy;
  17. import java.util.Collections;
  18. import java.util.LinkedList;
  19. import java.util.List;
  20. import org.springframework.aop.Advisor;
  21. import org.springframework.aop.TargetSource;
  22. import org.springframework.aop.support.AopUtils;
  23. import org.springframework.beans.factory.BeanFactory;
  24. import org.springframework.core.ControlFlow;
  25. import org.springframework.core.ControlFlowFactory;
  26. import org.springframework.core.OrderComparator;
  27. /**
  28.  * Abstract BeanPostProcessor implementation that creates AOP proxies. 
  29.  * This class is completely generic; it contains no special code to handle
  30.  * any particular aspects, such as pooling aspects.
  31.  *
  32.  * <p>Subclasses must implement the abstract findCandidateAdvisors() method
  33.  * to return a list of Advisors applying to any object. Subclasses can also
  34.  * override the inherited shouldSkip() method to exclude certain objects
  35.  * from autoproxying, but they must be careful to invoke the shouldSkip()
  36.  * method of this class, which tries to avoid circular reference problems
  37.  * and infinite loops.
  38.  *
  39.  * <p>Advisors or advices requiring ordering should implement the Ordered interface.
  40.  * This class sorts advisors by Ordered order value. Advisors that don't implement
  41.  * the Ordered interface will be considered to be unordered, and will appear
  42.  * at the end of the advisor chain in undefined order.
  43.  *
  44.  * @author Rod Johnson
  45.  * @see #findCandidateAdvisors
  46.  */
  47. public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
  48. /**
  49.  * We override this method to ensure that all candidate advisors are materialized
  50.  * under a stack trace including this bean. Otherwise, the dependencies won't
  51.  * be apparent to the circular-reference prevention strategy in AbstractBeanFactory.
  52.  */
  53. public void setBeanFactory(BeanFactory beanFactory) {
  54. super.setBeanFactory(beanFactory);
  55. findCandidateAdvisors();
  56. }
  57. protected Object[] getAdvicesAndAdvisorsForBean(Object bean, String name, TargetSource targetSource) {
  58. List advisors = findEligibleAdvisors(bean.getClass());
  59. if (advisors.isEmpty()) {
  60. return DO_NOT_PROXY;
  61. }
  62. advisors = sortAdvisors(advisors);
  63. return advisors.toArray();
  64. }
  65. /**
  66.  * Find all eligible advices and for autoproxying this class.
  67.  * @return the empty list, not null, if there are no pointcuts or interceptors
  68.  * @see #findCandidateAdvisors
  69.  */
  70. protected List findEligibleAdvisors(Class clazz) {
  71. List candidateAdvisors = findCandidateAdvisors();
  72. List eligibleAdvisors = new LinkedList();
  73. for (int i = 0; i < candidateAdvisors.size(); i++) {
  74. // Sun, give me generics, please!
  75. Advisor candidate = (Advisor) candidateAdvisors.get(i);
  76. if (AopUtils.canApply(candidate, clazz, null)) {
  77. eligibleAdvisors.add(candidate);
  78. if (logger.isInfoEnabled()) {
  79. logger.info("Candidate advisor [" + candidate + "] accepted for class [" + clazz.getName() + "]");
  80. }
  81. }
  82. else {
  83. if (logger.isInfoEnabled()) {
  84. logger.info("Candidate advisor [" + candidate + "] rejected for class [" + clazz.getName() + "]");
  85. }
  86. }
  87. }
  88. return eligibleAdvisors;
  89. }
  90. /**
  91.  * Sort advisors based on ordering.
  92.  * @see org.springframework.core.Ordered
  93.  * @see org.springframework.core.OrderComparator
  94.  */
  95. protected List sortAdvisors(List advisors) {
  96. Collections.sort(advisors, new OrderComparator());
  97. return advisors;
  98. }
  99. /**
  100.  * We override this to ensure that we don't get into circular reference hell
  101.  * when our own infrastructure (such as this class) depends on advisors that depend
  102.  * on beans... We use a ControlFlow object to check that we didn't arrived at this
  103.  * call via this classes findCandidateAdvisors() method.
  104.  * @see org.springframework.core.ControlFlow
  105.  */
  106. protected boolean shouldSkip(Object bean, String name) {
  107. // TODO consider pulling this test into AbstractBeanFactory.applyPostProcessors(),
  108. // to protect all PostProcessors.
  109. ControlFlow cflow = ControlFlowFactory.createControlFlow();
  110. return cflow.under(getClass(), "findCandidateAdvisors");
  111. }
  112. /**
  113.  * Find all candidate advisors to use in auto-proxying.
  114.  * @return list of Advisors
  115.  */
  116. protected abstract List findCandidateAdvisors();
  117. }