public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
/**
*如果拦截器链中的拦截器迭代调用完毕,这里开始调用target的函数,
*这个函数是通过反射机制完成的,具体实现在:AopUtils.invokeJoinpointUsingReflection方法里面。
*/
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethod
Matchers.size() - 1) {
return invokeJoinpoint();
}
//这里沿着定义好的 interceptorOrInterceptionAdvice链进行处理。
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptor
Index);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamic
MethodMatcher) {
/**
* Evaluate dynamic method matcher here: static part will already have
* been evaluated and found to match.
*/
/**
*这里对拦截器进行动态匹配的判断,还记得我们前面分析的pointcut吗?
*这里是触发进行匹配的地方,如果和定义的pointcut匹配,那么这个advice将会得到执行。
*/
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
// 如果不匹配,那么proceed会被递归调用,直到所有的拦截器都被运行过为止。
return proceed();
}
}
else {
/**
* It's an interceptor, so we just invoke it: The pointcut will have
* been evaluated statically before this object was constructed.
*/
//如果是interceptor,直接调用这个interceptor对应的方法。
return((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
public List getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class targetClass) {
/**
* This is somewhat tricky... we have to process introductions first,
* but we need to preserve order in the ultimate list.
*/
//advisor链已经在config中持有了,这里我们可以直接使用。
List interceptorList = new ArrayList
(config.getAdvisors().length);
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClass
Filter().matches(targetClass)) {
/**
*拦截器链是通过AdvisorAdapterRegistry来加入的,这个AdvisorAdapterRegistry
*对advice织入起了很大的作用,在后面的分析中会看到。
*/
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().gEtMethodMatcher();
//使用MethodMatchers的matches方法进行匹配判断。
if (MethodMatchers.matches(mm, method, targetClass, hasIntroductions)) {
if (mm.isRuntime()) {
/**
* Creating a new object instance in the getInterceptors()method
* isn't a problem as we normally cache created chains.
*/
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethod
Matcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(targetClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
// Determine whether the Advisors contain matching introductions.
private static boolean hasMatchingIntroductions(Advised config, ClasstargetClass) {
for (int i = 0; i < config.getAdvisors().length; i++) {
Advisor advisor = config.getAdvisors()[i];
if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (ia.getClassFilter().matches(targetClass)) {
return true;
}
}
}
return false;
}
private synchronized void initializeAdvisorChain() throws AopConfigException,
BeansException {
if (this.advisorChainInitialized) {
return;
}
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore
(probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.asList(this.
interceptorNames));
}
// Globals can't be last unless we specified a targetSource using the
property...
if (this.interceptorNames[this.interceptorNames.length - 1].endsWith
(GLOBAL_SUFFIX) &&
this.targetName == null && this.targetSource == EMPTY_TARGET_
SOURCE) {
throw new AopConfigException("Target required after globals");
}
// Materialize interceptor chain from bean names.
for (String name : this.interceptorNames) {
if (logger.isTraceEnabled()) {
logger.trace("Configuring advisor or advice '" + name + "'");
}
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors with
a ListableBeanFactory");
}
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
else {
// If we get here, we need to add a named interceptor.
// We must check if it's a singleton or prototype.
Object advice;
if (this.singleton || this.beanFactory.isSingleton(name)) {
// Add the real Advisor/Advice to the chain.
/**
* 这里是取得advisor的地方,是通过beanFactory取得的,
*把interceptorNames这个List中的interceptor名字交给
*beanFactory就可以了,然后通过调用BeanFactory的getBean去获取。
*/
advice = this.beanFactory.getBean(name);
}
else {
// It's a prototype Advice or Advisor: replace with a prototype.
/**
* Avoid unnecessary creation of prototype bean just for
*advisor chain initialization.
*/
advice = new PrototypePlaceholderAdvisor(name);
}
addAdvisorOnChainCreation(advice, name);
}
}
}
this.advisorChainInitialized = true;
}
public abstract class GlobalAdvisorAdapterRegistry {
/**
* Keep track of a single instance so we can return it to classes that request it.
*/
private static final AdvisorAdapterRegistry instance = new DefaultAdvisor
AdapterRegistry();
// Return the singleton DefaultAdvisorAdapterRegistry instance.
public static AdvisorAdapterRegistry getInstance() {
return instance;
}
}
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry,
Serializable {
//持有AdvisorAdaptor的List,它的Adapter是与实现Spring AOP的advice增强功能相对应的。
private final List adapters = new ArrayList(3);
// Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
/**
*这里把已有的advice实现的Adapter加入进来,有我们非常熟悉的
*MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice这些AOP的advice封装实现。
*/
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
//这里是在DefaultAdvisorChainFactory中启动的getInteceptors方法。
public MethodInterceptor[] getInterceptors(Advisor advisor) throwsUnknownAdvice
TypeException {
List interceptors = new ArrayList(3);
//从Advisor通知器配置中取得advice通知。
Advice advice = advisor.getAdvice();
//如果通知是MethodInterceptor类型的通知,直接加入interceptors的List中,不需要适配。
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
/**
*对通知进行适配,使用已经配置好的Adapter:MethodBeforeAdviceAdapter,
*AfterReturningAdviceAdapter以及ThrowsAdviceAdapter。
*然后从对应的adapter中取出封装好AOP编织功能的拦截器。
*/
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private MethodBeforeAdvice advice;
/**
* Create a new MethodBeforeAdviceInterceptor for the given advice.
* @param advice the MethodBeforeAdvice to wrap
*/
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
//这个invoke方法是拦截器的回调方法,会在代理对象的方法被调用的时候触发回调。
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
}
public class AfterReturningAdviceInterceptor implements MethodInterceptor,
AfterAdvice,Serializable {
private final AfterReturningAdvice advice;
/**
* Create a new AfterReturningAdviceInterceptor for the given advice.
* @param advice the AfterReturningAdvice to wrap
*/
public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(),
mi.getThis());
return retVal;
}
}
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// Get the interception chain for this method.
// 这里获得定义好的拦截器链。
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice
(method, targetClass);
/**
* Check whether we have any advice. If we don't, we can fallback on direct
* reflective invocation of the target, and avoid creating a MethodInvocation.
*/
// 如果没有设定拦截器,那么就直接调用target的对应方法。
if (chain.isEmpty()) {
/**
* We can skip creating a MethodInvocation: just invoke the target directly
* Note that the final invoker must be an InvokerInterceptor so we know it does
* nothing but a reflective operation on the target, and no hot swapping or
* fancy proxying.
*/
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
else {
// We need to create a method invocation...
// 如果有拦截器的设定,那么需要调用拦截器之后才调用目标对象的相应方法。
//通过构造一个ReflectiveMethodInvocation来实现。
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass,
chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
// Massage return value if necessary.
if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
/**
* Special case: it returned "this" and the return type of the method
* is type-compatible. Note that we can't help if the target sets
* a reference to itself in another returned object.
*/
retVal = proxy;
}
return retVal;
利用JavaScript进行对象排序,根据用户的年龄排序展示
<script>
var bob={
name;bob,
age:30
}
var peter={
name;peter,
age:30
}
var amy={
name;amy,
age:24
}
var mike={
name;mike,
age:29
}
var john={
FLP
One famous theory in distributed computing, known as FLP after the authors Fischer, Lynch, and Patterson, proved that in a distributed system with asynchronous communication and process crashes,
每一行命令都是用分号(;)作为结束
对于MySQL,第一件你必须牢记的是它的每一行命令都是用分号(;)作为结束的,但当一行MySQL被插入在PHP代码中时,最好把后面的分号省略掉,例如:
mysql_query("INSERT INTO tablename(first_name,last_name)VALUES('$first_name',$last_name')");
题目链接:zoj 3820 Building Fire Stations
题目大意:给定一棵树,选取两个建立加油站,问说所有点距离加油站距离的最大值的最小值是多少,并且任意输出一种建立加油站的方式。
解题思路:二分距离判断,判断函数的复杂度是o(n),这样的复杂度应该是o(nlogn),即使常数系数偏大,但是居然跑了4.5s,也是醉了。 判断函数里面做了3次bfs,但是每次bfs节点最多