你是如何构造 AspectJProxyFactory 的?
你应该是
AspectJProxyFactory factory = new AspectJProxyFactory(Car .class);
Car proxy = factory.getProxy();
这样吧,你注意这里你把 Car的 class 传入了,通过java的反射,所以不需要强转。这个 factory 就只能用来构建Car类型的
AspectJProxyFactory 的带参构造函数:
/** * Create a new AspectJProxyFactory. * <p>Will proxy all interfaces that the given target implements. * @param target the target object to be proxied */ public AspectJProxyFactory(Object target) { Assert.notNull(target, "Target object must not be null"); setInterfaces(ClassUtils.getAllInterfaces(target)); setTarget(target); }
AspectJProxyFactory 代码:
1 /* 2 * Copyright 2002-2015 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 17 package org.springframework.aop.aspectj.annotation; 18 19 import java.util.HashMap; 20 import java.util.List; 21 import java.util.Map; 22 23 import org.aspectj.lang.reflect.PerClauseKind; 24 25 import org.springframework.aop.Advisor; 26 import org.springframework.aop.aspectj.AspectJProxyUtils; 27 import org.springframework.aop.framework.AopConfigException; 28 import org.springframework.aop.framework.ProxyCreatorSupport; 29 import org.springframework.aop.support.AopUtils; 30 import org.springframework.core.annotation.AnnotationAwareOrderComparator; 31 import org.springframework.util.Assert; 32 import org.springframework.util.ClassUtils; 33 34 /** 35 * AspectJ-based proxy factory, allowing for programmatic building 36 * of proxies which include AspectJ aspects (code style as well 37 * Java 5 annotation style). 38 * 39 * @author Rob Harrop 40 * @author Juergen Hoeller 41 * @author Ramnivas Laddad 42 * @since 2.0 43 * @see #addAspect(Object) 44 * @see #addAspect(Class) 45 * @see #getProxy() 46 * @see #getProxy(ClassLoader) 47 * @see org.springframework.aop.framework.ProxyFactory 48 */ 49 @SuppressWarnings("serial") 50 public class AspectJProxyFactory extends ProxyCreatorSupport { 51 52 /** Cache for singleton aspect instances */ 53 private static final Map<Class<?>, Object> aspectCache = new HashMap<Class<?>, Object>(); 54 55 private final AspectJAdvisorFactory aspectFactory = new ReflectiveAspectJAdvisorFactory(); 56 57 58 /** 59 * Create a new AspectJProxyFactory. 60 */ 61 public AspectJProxyFactory() { 62 } 63 64 /** 65 * Create a new AspectJProxyFactory. 66 * <p>Will proxy all interfaces that the given target implements. 67 * @param target the target object to be proxied 68 */ 69 public AspectJProxyFactory(Object target) { 70 Assert.notNull(target, "Target object must not be null"); 71 setInterfaces(ClassUtils.getAllInterfaces(target)); 72 setTarget(target); 73 } 74 75 /** 76 * Create a new {@code AspectJProxyFactory}. 77 * No target, only interfaces. Must add interceptors. 78 */ 79 public AspectJProxyFactory(Class<?>[] interfaces) { 80 setInterfaces(interfaces); 81 } 82 83 84 /** 85 * Add the supplied aspect instance to the chain. The type of the aspect instance 86 * supplied must be a singleton aspect. True singleton lifecycle is not honoured when 87 * using this method - the caller is responsible for managing the lifecycle of any 88 * aspects added in this way. 89 * @param aspectInstance the AspectJ aspect instance 90 */ 91 public void addAspect(Object aspectInstance) { 92 Class<?> aspectClass = aspectInstance.getClass(); 93 String aspectName = aspectClass.getName(); 94 AspectMetadata am = createAspectMetadata(aspectClass, aspectName); 95 if (am.getAjType().getPerClause().getKind() != PerClauseKind.SINGLETON) { 96 throw new IllegalArgumentException( 97 "Aspect class [" + aspectClass.getName() + "] does not define a singleton aspect"); 98 } 99 addAdvisorsFromAspectInstanceFactory( 100 new SingletonMetadataAwareAspectInstanceFactory(aspectInstance, aspectName)); 101 } 102 103 /** 104 * Add an aspect of the supplied type to the end of the advice chain. 105 * @param aspectClass the AspectJ aspect class 106 */ 107 public void addAspect(Class<?> aspectClass) { 108 String aspectName = aspectClass.getName(); 109 AspectMetadata am = createAspectMetadata(aspectClass, aspectName); 110 MetadataAwareAspectInstanceFactory instanceFactory = createAspectInstanceFactory(am, aspectClass, aspectName); 111 addAdvisorsFromAspectInstanceFactory(instanceFactory); 112 } 113 114 115 /** 116 * Add all {@link Advisor Advisors} from the supplied {@link MetadataAwareAspectInstanceFactory} 117 * to the current chain. Exposes any special purpose {@link Advisor Advisors} if needed. 118 * @see AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary(List) 119 */ 120 private void addAdvisorsFromAspectInstanceFactory(MetadataAwareAspectInstanceFactory instanceFactory) { 121 List<Advisor> advisors = this.aspectFactory.getAdvisors(instanceFactory); 122 advisors = AopUtils.findAdvisorsThatCanApply(advisors, getTargetClass()); 123 AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors); 124 AnnotationAwareOrderComparator.sort(advisors); 125 addAdvisors(advisors); 126 } 127 128 /** 129 * Create an {@link AspectMetadata} instance for the supplied aspect type. 130 */ 131 private AspectMetadata createAspectMetadata(Class<?> aspectClass, String aspectName) { 132 AspectMetadata am = new AspectMetadata(aspectClass, aspectName); 133 if (!am.getAjType().isAspect()) { 134 throw new IllegalArgumentException("Class [" + aspectClass.getName() + "] is not a valid aspect type"); 135 } 136 return am; 137 } 138 139 /** 140 * Create a {@link MetadataAwareAspectInstanceFactory} for the supplied aspect type. If the aspect type 141 * has no per clause, then a {@link SingletonMetadataAwareAspectInstanceFactory} is returned, otherwise 142 * a {@link PrototypeAspectInstanceFactory} is returned. 143 */ 144 private MetadataAwareAspectInstanceFactory createAspectInstanceFactory( 145 AspectMetadata am, Class<?> aspectClass, String aspectName) { 146 147 MetadataAwareAspectInstanceFactory instanceFactory = null; 148 if (am.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { 149 // Create a shared aspect instance. 150 Object instance = getSingletonAspectInstance(aspectClass); 151 instanceFactory = new SingletonMetadataAwareAspectInstanceFactory(instance, aspectName); 152 } 153 else { 154 // Create a factory for independent aspect instances. 155 instanceFactory = new SimpleMetadataAwareAspectInstanceFactory(aspectClass, aspectName); 156 } 157 return instanceFactory; 158 } 159 160 /** 161 * Get the singleton aspect instance for the supplied aspect type. An instance 162 * is created if one cannot be found in the instance cache. 163 */ 164 private Object getSingletonAspectInstance(Class<?> aspectClass) { 165 synchronized (aspectCache) { 166 Object instance = aspectCache.get(aspectClass); 167 if (instance != null) { 168 return instance; 169 } 170 try { 171 instance = aspectClass.newInstance(); 172 aspectCache.put(aspectClass, instance); 173 return instance; 174 } 175 catch (InstantiationException ex) { 176 throw new AopConfigException("Unable to instantiate aspect class [" + aspectClass.getName() + "]", ex); 177 } 178 catch (IllegalAccessException ex) { 179 throw new AopConfigException("Cannot access aspect class [" + aspectClass.getName() + "]", ex); 180 } 181 } 182 } 183 184 185 /** 186 * Create a new proxy according to the settings in this factory. 187 * <p>Can be called repeatedly. Effect will vary if we've added 188 * or removed interfaces. Can add and remove interceptors. 189 * <p>Uses a default class loader: Usually, the thread context class loader 190 * (if necessary for proxy creation). 191 * @return the new proxy 192 */ 193 @SuppressWarnings("unchecked") 194 public <T> T getProxy() { 195 return (T) createAopProxy().getProxy(); 196 } 197 198 /** 199 * Create a new proxy according to the settings in this factory. 200 * <p>Can be called repeatedly. Effect will vary if we've added 201 * or removed interfaces. Can add and remove interceptors. 202 * <p>Uses the given class loader (if necessary for proxy creation). 203 * @param classLoader the class loader to create the proxy with 204 * @return the new proxy 205 */ 206 @SuppressWarnings("unchecked") 207 public <T> T getProxy(ClassLoader classLoader) { 208 return (T) createAopProxy().getProxy(classLoader); 209 } 210 211 }
问题就在这 “通过java的反射,所以不需要强转”,这个反射代码是如何写的呢?
@遁地龙卷风: 看构造函数的第三行代码:setTarget(target);
这个是在父类定义的:
1 /** 2 * Set the given object as target. 设置所给的对象作为目标对象 3 * Will create a SingletonTargetSource for the object. 4 * @see #setTargetSource 5 * @see org.springframework.aop.target.SingletonTargetSource 6 */ 7 public void setTarget(Object target) { 8 setTargetSource(new SingletonTargetSource(target)); 9 }
@遁地龙卷风: http://www.tuicool.com/articles/fEFrInJ 这里是 TargetSource 的介绍
Car proxy = (Car)factory.getProxy();
Car proxy = factory.getProxy(); 没用强制转换,源码就是这样
@遁地龙卷风: 你是问它是怎么做到直接得到car而不需要转换吗?
可以查看到getProxy()的封装代码吗?