下面列出了怎么用java.lang.reflect.Proxy的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
@SuppressWarnings("unchecked")
public void testEntityManagerProxyIsProxy() {
EntityManager em = createContainerManagedEntityManager();
assertTrue(Proxy.isProxyClass(em.getClass()));
Query q = em.createQuery("select p from Person as p");
List<Person> people = q.getResultList();
assertTrue(people.isEmpty());
assertTrue("Should be open to start with", em.isOpen());
try {
em.close();
fail("Close should not work on container managed EM");
}
catch (IllegalStateException ex) {
// OK
}
assertTrue(em.isOpen());
}
@Test
public void testResolveProxyClass() throws Exception {
final String interfaceName = "UserDefinedInterface";
final String proxyName = "UserProxy";
try (URLClassLoader userClassLoader = createClassLoader(interfaceName, proxyName)) {
Class<?> userInterface = Class.forName(interfaceName, false, userClassLoader);
InvocationHandler userProxy = (InvocationHandler) Class.forName(proxyName, false, userClassLoader)
.newInstance();
Object proxy = Proxy.newProxyInstance(userClassLoader, new Class[]{userInterface}, userProxy);
byte[] serializeObject = InstantiationUtil.serializeObject(proxy);
Object deserializedProxy = InstantiationUtil.deserializeObject(serializeObject, userClassLoader);
assertNotNull(deserializedProxy);
}
}
/**
* Generate proxy arrays.
*/
Proxy[][] genArrays(int size, int narrays) throws Exception {
Class proxyClass =
Proxy.getProxyClass(DummyInterface.class.getClassLoader(),
new Class[] { DummyInterface.class });
Constructor proxyCons =
proxyClass.getConstructor(new Class[] { InvocationHandler.class });
Object[] consArgs = new Object[] { new DummyHandler() };
Proxy[][] arrays = new Proxy[narrays][size];
for (int i = 0; i < narrays; i++) {
for (int j = 0; j < size; j++) {
arrays[i][j] = (Proxy) proxyCons.newInstance(consArgs);
}
}
return arrays;
}
/**
* Generate proxy class descriptors.
*/
ObjectStreamClass[] genDescs() {
ClassLoader ldr = ProxyClassDesc.class.getClassLoader();
Class[] ifaces = new Class[3];
Class[] a =
new Class[] { A1.class, A2.class, A3.class, A4.class, A5.class };
Class[] b =
new Class[] { B1.class, B2.class, B3.class, B4.class, B5.class };
Class[] c =
new Class[] { C1.class, C2.class, C3.class, C4.class, C5.class };
ObjectStreamClass[] descs =
new ObjectStreamClass[a.length * b.length * c.length];
int n = 0;
for (int i = 0; i < a.length; i++) {
ifaces[0] = a[i];
for (int j = 0; j < b.length; j++) {
ifaces[1] = b[j];
for (int k = 0; k < c.length; k++) {
ifaces[2] = c[k];
Class proxyClass = Proxy.getProxyClass(ldr, ifaces);
descs[n++] = ObjectStreamClass.lookup(proxyClass);
}
}
}
return descs;
}
/**
* Transfroms a proxy implementing T in a proxy implementing T plus
* NotificationEmitter
*
**/
public static <T> T makeNotificationEmitter(T proxy,
Class<T> mbeanInterface) {
if (proxy instanceof NotificationEmitter)
return proxy;
if (proxy == null) return null;
if (!(proxy instanceof Proxy))
throw new IllegalArgumentException("not a "+Proxy.class.getName());
final Proxy p = (Proxy) proxy;
final InvocationHandler handler =
Proxy.getInvocationHandler(proxy);
if (!(handler instanceof MBeanServerInvocationHandler))
throw new IllegalArgumentException("not a JMX Proxy");
final MBeanServerInvocationHandler h =
(MBeanServerInvocationHandler)handler;
final ObjectName name = h.getObjectName();
final MBeanServerConnection mbs = h.getMBeanServerConnection();
final boolean isMXBean = h.isMXBean();
final T newProxy;
if (isMXBean)
newProxy = JMX.newMXBeanProxy(mbs,name,mbeanInterface,true);
else
newProxy = JMX.newMBeanProxy(mbs,name,mbeanInterface,true);
return newProxy;
}
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 创建代理,这里有两种代理类型 1. JDK 动态代理 2. CGLIB 动态代理
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
@Test
public void testCircularCollectionBeansStartingWithList() {
this.beanFactory.getBean("circularList");
TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionBeansBean");
List list = bean.getSomeList();
assertTrue(Proxy.isProxyClass(list.getClass()));
assertEquals(1, list.size());
assertEquals(bean, list.get(0));
Set set = bean.getSomeSet();
assertFalse(Proxy.isProxyClass(set.getClass()));
assertEquals(1, set.size());
assertTrue(set.contains(bean));
Map map = bean.getSomeMap();
assertFalse(Proxy.isProxyClass(map.getClass()));
assertEquals(1, map.size());
assertEquals(bean, map.get("foo"));
}
@Override
public ObjectInputFilter.Status checkInput(FilterInfo filter) {
Class<?> serialClass = filter.serialClass();
System.out.printf(" checkInput: class: %s, arrayLen: %d, refs: %d, depth: %d, bytes; %d%n",
serialClass, filter.arrayLength(), filter.references(),
filter.depth(), filter.streamBytes());
count++;
if (serialClass != null) {
if (serialClass.getName().contains("$$Lambda$")) {
// TBD: proper identification of serialized Lambdas?
// Fold the serialized Lambda into the SerializedLambda type
classes.add(SerializedLambda.class);
} else if (Proxy.isProxyClass(serialClass)) {
classes.add(Proxy.class);
} else {
classes.add(serialClass);
}
}
this.maxArray = Math.max(this.maxArray, filter.arrayLength());
this.maxRefs = Math.max(this.maxRefs, filter.references());
this.maxDepth = Math.max(this.maxDepth, filter.depth());
this.maxBytes = Math.max(this.maxBytes, filter.streamBytes());
return ObjectInputFilter.Status.UNDECIDED;
}
/**
* Write and read proxy arrays to/from a stream. The benchmark is run in
* batches, with each batch consisting of a fixed number of read/write
* cycles. The ObjectOutputStream is reset after each batch of cycles has
* completed.
* Arguments: <array size> <# batches> <# cycles per batch>
*/
public long run(String[] args) throws Exception {
int size = Integer.parseInt(args[0]);
int nbatches = Integer.parseInt(args[1]);
int ncycles = Integer.parseInt(args[2]);
Proxy[][] arrays = genArrays(size, ncycles);
StreamBuffer sbuf = new StreamBuffer();
ObjectOutputStream oout =
new ObjectOutputStream(sbuf.getOutputStream());
ObjectInputStream oin =
new ObjectInputStream(sbuf.getInputStream());
doReps(oout, oin, sbuf, arrays, 1); // warmup
long start = System.currentTimeMillis();
doReps(oout, oin, sbuf, arrays, nbatches);
return System.currentTimeMillis() - start;
}
public <M extends Metadata> UnboundMetadata<M> apply(
Class<? extends RelNode> relClass,
final Class<? extends M> metadataClass) {
final UnboundMetadata<M> function =
underlyingProvider.apply(relClass, metadataClass);
if (function == null) {
return null;
}
// TODO jvs 30-Mar-2006: Use meta-metadata to decide which metadata
// query results can stay fresh until the next Ice Age.
return (rel, mq) -> {
final Metadata metadata = function.bind(rel, mq);
return metadataClass.cast(
Proxy.newProxyInstance(metadataClass.getClassLoader(),
new Class[]{metadataClass},
new CachingInvocationHandler(metadata)));
};
}
/**
* Builds and returns a {@link KernelProxy} with the configured parameters.
*
* @return A proxy for the remote kernel.
* @throws KernelUnavailableException If the remote kernel is not reachable for some reason.
* @throws CredentialsException If the client login with the remote kernel failed, e.g. because of
* incorrect login data.
* @see RemoteKernel#pollEvents(ClientID, long)
*/
@SuppressWarnings("deprecation")
public KernelProxy build()
throws KernelUnavailableException, CredentialsException {
// Create an invocation handler that does the actual work.
ProxyInvocationHandler handler
= new ProxyInvocationHandler(socketFactoryProvider,
host,
port,
userName,
password,
eventFilter,
eventPollInterval,
eventPollTimeout);
// Return a proxy instance with the created handler.
// Create a proxy instance with the handler and return it.
KernelProxy proxy
= (KernelProxy) Proxy.newProxyInstance(Kernel.class.getClassLoader(),
new Class<?>[] {KernelProxy.class},
handler);
proxy.login();
return proxy;
}
/**
* Actually create the EntityManager proxy.
* @param rawEm raw EntityManager
* @param emIfc the (potentially vendor-specific) EntityManager
* interface to proxy, or {@code null} for default detection of all interfaces
* @param cl the ClassLoader to use for proxy creation (maybe {@code null})
* @param exceptionTranslator the PersistenceException translator to use
* @param jta whether to create a JTA-aware EntityManager
* (or {@code null} if not known in advance)
* @param containerManaged whether to follow container-managed EntityManager
* or application-managed EntityManager semantics
* @param synchronizedWithTransaction whether to automatically join ongoing
* transactions (according to the JPA 2.1 SynchronizationType rules)
* @return the EntityManager proxy
*/
private static EntityManager createProxy(
EntityManager rawEm, @Nullable Class<? extends EntityManager> emIfc, @Nullable ClassLoader cl,
@Nullable PersistenceExceptionTranslator exceptionTranslator, @Nullable Boolean jta,
boolean containerManaged, boolean synchronizedWithTransaction) {
Assert.notNull(rawEm, "EntityManager must not be null");
Set<Class<?>> ifcs = new LinkedHashSet<>();
if (emIfc != null) {
ifcs.add(emIfc);
}
else {
ifcs.addAll(ClassUtils.getAllInterfacesForClassAsSet(rawEm.getClass(), cl));
}
ifcs.add(EntityManagerProxy.class);
return (EntityManager) Proxy.newProxyInstance(
(cl != null ? cl : ExtendedEntityManagerCreator.class.getClassLoader()),
ClassUtils.toClassArray(ifcs),
new ExtendedEntityManagerInvocationHandler(
rawEm, exceptionTranslator, jta, containerManaged, synchronizedWithTransaction));
}
/**
* Returns ObjectStreamField array describing the serializable fields of
* the given class. Serializable fields backed by an actual field of the
* class are represented by ObjectStreamFields with corresponding non-null
* Field objects. Throws InvalidClassException if the (explicitly
* declared) serializable fields are invalid.
*/
private static ObjectStreamField[] getSerialFields(Class<?> cl)
throws InvalidClassException
{
ObjectStreamField[] fields;
if (Serializable.class.isAssignableFrom(cl) &&
!Externalizable.class.isAssignableFrom(cl) &&
!Proxy.isProxyClass(cl) &&
!cl.isInterface())
{
if ((fields = getDeclaredSerialFields(cl)) == null) {
fields = getDefaultSerialFields(cl);
}
Arrays.sort(fields);
} else {
fields = NO_FIELDS;
}
return fields;
}
@SuppressWarnings("unchecked")
static <A extends Annotation> A synthesizeAnnotation(A annotation, @Nullable Object annotatedElement) {
if (annotation instanceof SynthesizedAnnotation || hasPlainJavaAnnotationsOnly(annotatedElement)) {
return annotation;
}
Class<? extends Annotation> annotationType = annotation.annotationType();
if (!isSynthesizable(annotationType)) {
return annotation;
}
DefaultAnnotationAttributeExtractor attributeExtractor =
new DefaultAnnotationAttributeExtractor(annotation, annotatedElement);
InvocationHandler handler = new SynthesizedAnnotationInvocationHandler(attributeExtractor);
// Can always expose Spring's SynthesizedAnnotation marker since we explicitly check for a
// synthesizable annotation before (which needs to declare @AliasFor from the same package)
Class<?>[] exposedInterfaces = new Class<?>[] {annotationType, SynthesizedAnnotation.class};
return (A) Proxy.newProxyInstance(annotation.getClass().getClassLoader(), exposedInterfaces, handler);
}
@Test
@SuppressWarnings("unchecked")
public void testEntityManagerProxyIsProxy() {
EntityManager em = createContainerManagedEntityManager();
assertTrue(Proxy.isProxyClass(em.getClass()));
Query q = em.createQuery("select p from Person as p");
List<Person> people = q.getResultList();
assertTrue(people.isEmpty());
assertTrue("Should be open to start with", em.isOpen());
try {
em.close();
fail("Close should not work on container managed EM");
}
catch (IllegalStateException ex) {
// OK
}
assertTrue(em.isOpen());
}
/**
* ObjectInputStream.resolveProxyClass has some funky way of using
* the incorrect class loader to resolve proxy classes, let's do it our way instead
*/
@Override
protected Class<?> resolveProxyClass(String[] interfaces)
throws IOException, ClassNotFoundException {
ClassLoader latestLoader;
if (classLoaders != null && classLoaders.length > 0) {
latestLoader = classLoaders[0];
} else {
latestLoader = null;
}
ClassLoader nonPublicLoader = null;
boolean hasNonPublicInterface = false;
// define proxy in class loader of non-public interface(s), if any
Class<?>[] classObjs = new Class[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
Class<?> cl = this.resolveClass(interfaces[i]);
if (latestLoader==null) latestLoader = cl.getClassLoader();
if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
if (hasNonPublicInterface) {
if (nonPublicLoader != cl.getClassLoader()) {
throw new IllegalAccessError(
sm.getString("replicationStream.conflict"));
}
} else {
nonPublicLoader = cl.getClassLoader();
hasNonPublicInterface = true;
}
}
classObjs[i] = cl;
}
try {
return Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader
: latestLoader, classObjs);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(null, e);
}
}
/**
* Define a proxy class in the given class loader. The proxy
* class will implement the given interfaces Classes.
*/
private static Class<?> loadProxyClass(ClassLoader loader, Class<?>[] interfaces)
throws ClassNotFoundException
{
try {
return Proxy.getProxyClass(loader, interfaces);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(
"error creating dynamic proxy class", e);
}
}
protected Object wrapDataSource(Object datasource, String username, String password) throws NamingException {
try {
DataSourceHandler handler =
new DataSourceHandler((DataSource)datasource, username, password);
return Proxy.newProxyInstance(datasource.getClass().getClassLoader(),
datasource.getClass().getInterfaces(), handler);
}catch (Exception x) {
if (x instanceof InvocationTargetException) {
Throwable cause = x.getCause();
if (cause instanceof ThreadDeath) {
throw (ThreadDeath) cause;
}
if (cause instanceof VirtualMachineError) {
throw (VirtualMachineError) cause;
}
if (cause instanceof Exception) {
x = (Exception) cause;
}
}
if (x instanceof NamingException) throw (NamingException)x;
else {
NamingException nx = new NamingException(x.getMessage());
nx.initCause(x);
throw nx;
}
}
}
private static boolean isReflectiveCheckNeeded(final Class<?> type, final boolean isStatic) {
// special handling for Proxy subclasses
if (Proxy.class.isAssignableFrom(type)) {
if (Proxy.isProxyClass(type)) {
// real Proxy class - filter only static access
return isStatic;
}
// fake Proxy subclass - filter it always!
return true;
}
// check for any other reflective Class
return isReflectionClass(type);
}
public static void main(String[] args) {
RealSubject rs = new RealSubject();
DynamicSubject ds = new DynamicSubject(rs);
// 获取 class 对象,因为后面创建动态代理的类需要类加载器,然后通过 class 对象和类加载器创建对象
Class<?> cls = rs.getClass();
Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(),
cls.getInterfaces(), ds);
subject.request();
System.out.println(subject.getClass());
System.out.println(subject.getClass().getSuperclass());
}
/**
* Helper method that finds interceptor instance in interceptor chain of a
* proxied class.
*
* @param proxy
* Proxy class
* @param clazz
* Interceptor class that we are looking for
* @return Instance of <code>clazz</code>
*/
private static <T extends JdbcInterceptor> T findInterceptor(Object proxy,
Class<T> clazz) {
JdbcInterceptor interceptor = (JdbcInterceptor) Proxy
.getInvocationHandler(proxy);
while (interceptor != null) {
if (clazz.isInstance(interceptor)) {
return clazz.cast(interceptor);
}
interceptor = interceptor.getNext();
}
return null;
}
private Object createListener() {
clz_DecodeTaskCompletionListener = load("com/tencent/mobileqq/util/FaceDecoder$DecodeTaskCompletionListener");
if (clz_DecodeTaskCompletionListener == null) {
Class[] argt;
Method[] ms = class_FaceDecoder.getDeclaredMethods();
for (Method m : ms) {
if (!m.getReturnType().equals(void.class)) continue;
argt = m.getParameterTypes();
if (argt.length != 1) continue;
if (argt[0].equals(load("com/tencent/common/app/AppInterface"))) continue;
clz_DecodeTaskCompletionListener = argt[0];
}
}
return Proxy.newProxyInstance(clz_DecodeTaskCompletionListener.getClassLoader(), new Class[]{clz_DecodeTaskCompletionListener}, this);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (Proxy.isProxyClass(obj.getClass())) {
obj = Proxy.getInvocationHandler(obj);
}
return this == obj;
}
public static void main(String[] args) throws Exception {
Phaser phaser = new Phaser(threads) {
@Override
protected boolean onAdvance(int phase, int registeredParties) {
// install new ClassLoader on each advance
classLoader = new CL();
return terminate;
}
};
ExecutorService exe = Executors.newFixedThreadPool(threads);
for (int i = 0; i < threads; i++) {
exe.execute(() -> {
while (phaser.arriveAndAwaitAdvance() >= 0) {
Class<?> proxyClass = Proxy.getProxyClass(classLoader, Runnable.class);
if (!Proxy.isProxyClass(proxyClass)) {
racesDetected.incrementAndGet();
}
}
});
}
Thread.sleep(5000L);
terminate = true;
exe.shutdown();
exe.awaitTermination(5L, TimeUnit.SECONDS);
System.out.println(racesDetected.get() + " races detected");
if (racesDetected.get() != 0) {
throw new RuntimeException(racesDetected.get() + " races detected");
}
}
/**
* Test the monitor notifications.
*/
public int monitorNotifications() throws Exception {
server = MBeanServerFactory.newMBeanServer();
MBeanServerForwarderInvocationHandler mbsfih =
(MBeanServerForwarderInvocationHandler)
Proxy.getInvocationHandler(server);
mbsfih.setGetAttributeException(
new ReflectionException(new RuntimeException(),
"Test ReflectionException"));
domain = server.getDefaultDomain();
obsObjName = ObjectName.getInstance(domain + ":type=ObservedObject");
server.registerMBean(new ObservedObject(), obsObjName);
echo(">>> ----------------------------------------");
int error = counterMonitorNotification();
echo(">>> ----------------------------------------");
error += gaugeMonitorNotification();
echo(">>> ----------------------------------------");
error += stringMonitorNotification();
echo(">>> ----------------------------------------");
return error;
}
private static Object annotationToField(Object x) {
// An annotation element cannot have a null value but never mind
if (x == null)
return null;
if (x instanceof Number || x instanceof String ||
x instanceof Character || x instanceof Boolean ||
x instanceof String[])
return x;
// Remaining possibilities: array of primitive (e.g. int[]),
// enum, class, array of enum or class.
Class<?> c = x.getClass();
if (c.isArray()) {
if (c.getComponentType().isPrimitive())
return x;
Object[] xx = (Object[]) x;
String[] ss = new String[xx.length];
for (int i = 0; i < xx.length; i++)
ss[i] = (String) annotationToField(xx[i]);
return ss;
}
if (x instanceof Class<?>)
return ((Class<?>) x).getName();
if (x instanceof Enum<?>)
return ((Enum<?>) x).name();
// The only other possibility is that the value is another
// annotation, or that the language has evolved since this code
// was written. We don't allow for either of those currently.
// If it is indeed another annotation, then x will be a proxy
// with an unhelpful name like $Proxy2. So we extract the
// proxy's interface to use that in the exception message.
if (Proxy.isProxyClass(c))
c = c.getInterfaces()[0]; // array "can't be empty"
throw new IllegalArgumentException("Illegal type for annotation " +
"element using @DescriptorKey: " + c.getName());
}
@Test
public void testCreateException() throws Exception {
final String jndiName = "foo";
final CreateException cex = new CreateException();
final MyHome home = mock(MyHome.class);
given(home.create()).willThrow(cex);
JndiTemplate jt = new JndiTemplate() {
@Override
public Object lookup(String name) throws NamingException {
// parameterize
assertTrue(name.equals(jndiName));
return home;
}
};
LocalStatelessSessionProxyFactoryBean fb = new LocalStatelessSessionProxyFactoryBean();
fb.setJndiName(jndiName);
fb.setResourceRef(false); // no java:comp/env prefix
fb.setBusinessInterface(MyBusinessMethods.class);
assertEquals(fb.getBusinessInterface(), MyBusinessMethods.class);
fb.setJndiTemplate(jt);
// Need lifecycle methods
fb.afterPropertiesSet();
MyBusinessMethods mbm = (MyBusinessMethods) fb.getObject();
assertTrue(Proxy.isProxyClass(mbm.getClass()));
try {
mbm.getValue();
fail("Should have failed to create EJB");
}
catch (EjbAccessException ex) {
assertSame(cex, ex.getCause());
}
}
public void checkLoad(Proxy proxy, ClassLoader expectedLoader) {
ClassLoader proxyLoader = proxy.getClass().getClassLoader();
String proxyAnnotation =
RMIClassLoader.getClassAnnotation(proxy.getClass());
if ((proxyAnnotation == null) ||
!proxyAnnotation.equals(publicUrl.toString()))
{
TestLibrary.bomb("proxy class had incorrect annotation: " +
proxyAnnotation);
} else {
System.err.println("proxy class had correct annotation: " +
proxyAnnotation);
}
boolean proxyOk = false;
if (boomerangSemantics) {
ClassLoader ctxLoader =
Thread.currentThread().getContextClassLoader();
if (proxyLoader == ctxLoader) {
proxyOk = true;
}
} else if (proxyLoader.getClass().
getName().indexOf("sun.rmi") >= 0)
{
proxyOk = true;
}
if (proxyOk) {
System.err.println("\ncase5: proxy loaded from" +
" correct loader: " + proxyLoader);
} else {
TestLibrary.bomb("case5: proxy interface loaded from " +
"incorrect loader: " + proxyLoader);
}
}
@Test
public void testBeanNameAutoProxyCreatorWithFactoryBeanProxy() {
StaticApplicationContext sac = new StaticApplicationContext();
sac.registerSingleton("testInterceptor", TestInterceptor.class);
RootBeanDefinition proxyCreator = new RootBeanDefinition(BeanNameAutoProxyCreator.class);
proxyCreator.getPropertyValues().add("interceptorNames", "testInterceptor");
proxyCreator.getPropertyValues().add("beanNames", "singletonToBeProxied,&singletonFactoryToBeProxied");
sac.getDefaultListableBeanFactory().registerBeanDefinition("beanNameAutoProxyCreator", proxyCreator);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
sac.getDefaultListableBeanFactory().registerBeanDefinition("singletonToBeProxied", bd);
sac.registerSingleton("singletonFactoryToBeProxied", DummyFactory.class);
sac.refresh();
ITestBean singletonToBeProxied = (ITestBean) sac.getBean("singletonToBeProxied");
assertTrue(Proxy.isProxyClass(singletonToBeProxied.getClass()));
TestInterceptor ti = (TestInterceptor) sac.getBean("testInterceptor");
int initialNr = ti.nrOfInvocations;
singletonToBeProxied.getName();
assertEquals(initialNr + 1, ti.nrOfInvocations);
FactoryBean<?> factory = (FactoryBean<?>) sac.getBean("&singletonFactoryToBeProxied");
assertTrue(Proxy.isProxyClass(factory.getClass()));
TestBean tb = (TestBean) sac.getBean("singletonFactoryToBeProxied");
assertFalse(AopUtils.isAopProxy(tb));
assertEquals(initialNr + 3, ti.nrOfInvocations);
tb.getAge();
assertEquals(initialNr + 3, ti.nrOfInvocations);
}
@SuppressWarnings("unchecked")
public T buildJdkProxy() {
CONSUMED_SERVICES.add(new ServiceLocator(group, service, version));
RSocketRequesterRpcProxy proxy = getRequesterProxy();
return (T) Proxy.newProxyInstance(
serviceInterface.getClassLoader(),
new Class[]{serviceInterface},
proxy);
}