Search in sources :

Example 6 with TargetSource

use of cn.taketoday.aop.TargetSource in project today-framework by TAKETODAY.

the class JdkDynamicAopProxy method invoke.

/**
 * Implementation of {@code InvocationHandler.invoke}.
 * <p>Callers will see exactly the exception thrown by the target,
 * unless a hook method throws an exception.
 */
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object oldProxy = null;
    boolean setProxyContext = false;
    TargetSource targetSource = advised.getTargetSource();
    Object target = null;
    try {
        if (!equalsDefined && ReflectionUtils.isEqualsMethod(method)) {
            // The target does not implement the equals(Object) method itself.
            return equals(args[0]);
        } else if (!hashCodeDefined && ReflectionUtils.isHashCodeMethod(method)) {
            // The target does not implement the hashCode() method itself.
            return hashCode();
        } else {
            Class<?> declaringClass = method.getDeclaringClass();
            if (declaringClass == DecoratingProxy.class) {
                // There is only getDecoratedClass() declared -> dispatch to proxy config.
                return AopProxyUtils.ultimateTargetClass(advised);
            } else if (!advised.isOpaque()) {
                if (declaringClass.isInterface() && declaringClass.isAssignableFrom(Advised.class)) {
                    // Service invocations on ProxyConfig with the proxy config...
                    return AopUtils.invokeJoinpointUsingReflection(advised, method, args);
                }
            }
        }
        if (advised.isExposeProxy()) {
            // Make invocation available if necessary.
            oldProxy = AopContext.setCurrentProxy(proxy);
            setProxyContext = true;
        }
        // Get as late as possible to minimize the time we "own" the target,
        // in case it comes from a pool.
        target = targetSource.getTarget();
        Class<?> targetClass = (target != null ? target.getClass() : null);
        // Get the interception chain for this method.
        MethodInterceptor[] chain = advised.getInterceptors(method, targetClass);
        Object retVal;
        // reflective invocation of the target, and avoid creating a MethodInvocation.
        if (ObjectUtils.isEmpty(chain)) {
            // 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.
            Object[] argsToUse = ClassUtils.adaptArgumentsIfNecessary(method, args);
            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
        } else {
            // Proceed to the join-point through the interceptor chain.
            retVal = new DefaultMethodInvocation(proxy, target, method, targetClass, args, chain).proceed();
        }
        // Massage return value if necessary
        Class<?> returnType;
        if (retVal != null && retVal == target && (returnType = method.getReturnType()) != Object.class && returnType.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;
        }
        if (retVal == null) {
            returnType = method.getReturnType();
            if (returnType != Void.TYPE && returnType.isPrimitive()) {
                throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
            }
        }
        return retVal;
    } finally {
        if (target != null && !targetSource.isStatic()) {
            // Must have come from TargetSource.
            targetSource.releaseTarget(target);
        }
        if (setProxyContext) {
            // Restore old proxy.
            AopContext.setCurrentProxy(oldProxy);
        }
    }
}
Also used : TargetSource(cn.taketoday.aop.TargetSource) MethodInterceptor(org.aopalliance.intercept.MethodInterceptor) AopInvocationException(cn.taketoday.aop.AopInvocationException) DecoratingProxy(cn.taketoday.core.DecoratingProxy) Nullable(cn.taketoday.lang.Nullable)

Example 7 with TargetSource

use of cn.taketoday.aop.TargetSource in project today-framework by TAKETODAY.

the class StandardProxyInvoker method dynamicAdvisedProceed.

public static Object dynamicAdvisedProceed(Object proxy, AdvisedSupport advised, TargetInvocation targetInv, Object[] args) throws Throwable {
    Object target = null;
    Object oldProxy = null;
    boolean restore = false;
    final TargetSource targetSource = advised.getTargetSource();
    try {
        if (advised.isExposeProxy()) {
            // Make invocation available if necessary.
            oldProxy = AopContext.setCurrentProxy(proxy);
            restore = true;
        }
        target = targetSource.getTarget();
        final MethodInterceptor[] interceptors = targetInv.getDynamicInterceptors(advised);
        // but just use MethodInvoker invocation of the target.
        if (ObjectUtils.isEmpty(interceptors)) {
            return targetInv.proceed(target, args);
        }
        // We need to create a DynamicStandardMethodInvocation...
        final Object retVal = new DynamicStandardMethodInvocation(proxy, target, targetInv, args, interceptors).proceed();
        assertReturnValue(retVal, targetInv.getMethod());
        return retVal;
    } finally {
        if (target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
        }
        if (restore) {
            // Restore old proxy.
            AopContext.setCurrentProxy(oldProxy);
        }
    }
}
Also used : TargetSource(cn.taketoday.aop.TargetSource) MethodInterceptor(org.aopalliance.intercept.MethodInterceptor)

Example 8 with TargetSource

use of cn.taketoday.aop.TargetSource in project today-framework by TAKETODAY.

the class MBeanServerConnectionFactoryBean method createLazyConnection.

/**
 * Creates lazy proxies for the {@code JMXConnector} and {@code MBeanServerConnection}.
 */
private void createLazyConnection() {
    this.connectorTargetSource = new JMXConnectorLazyInitTargetSource();
    TargetSource connectionTargetSource = new MBeanServerConnectionLazyInitTargetSource();
    this.connector = (JMXConnector) new ProxyFactory(JMXConnector.class, this.connectorTargetSource).getProxy(this.beanClassLoader);
    this.connection = (MBeanServerConnection) new ProxyFactory(MBeanServerConnection.class, connectionTargetSource).getProxy(this.beanClassLoader);
}
Also used : AbstractLazyCreationTargetSource(cn.taketoday.aop.target.AbstractLazyCreationTargetSource) TargetSource(cn.taketoday.aop.TargetSource) ProxyFactory(cn.taketoday.aop.framework.ProxyFactory) JMXConnector(javax.management.remote.JMXConnector) MBeanServerConnection(javax.management.MBeanServerConnection)

Example 9 with TargetSource

use of cn.taketoday.aop.TargetSource in project today-framework by TAKETODAY.

the class AbstractAopProxyTests method testProxyIsBoundBeforeTargetSourceInvoked.

@Test
public void testProxyIsBoundBeforeTargetSourceInvoked() {
    final TestBean target = new TestBean();
    ProxyFactory pf = new ProxyFactory(target);
    pf.addAdvice(new DebugInterceptor());
    pf.setExposeProxy(true);
    final ITestBean proxy = (ITestBean) createProxy(pf);
    Advised config = (Advised) proxy;
    // This class just checks proxy is bound before getTarget() call
    config.setTargetSource(new TargetSource() {

        @Override
        public Class<?> getTargetClass() {
            return TestBean.class;
        }

        @Override
        public boolean isStatic() {
            return false;
        }

        @Override
        public Object getTarget() throws Exception {
            assertThat(AopContext.currentProxy()).isEqualTo(proxy);
            return target;
        }

        @Override
        public void releaseTarget(Object target) throws Exception {
        }
    });
    // Just test anything: it will fail if context wasn't found
    assertThat(proxy.getAge()).isEqualTo(0);
}
Also used : ITestBean(cn.taketoday.beans.testfixture.beans.ITestBean) HotSwappableTargetSource(cn.taketoday.aop.target.HotSwappableTargetSource) TargetSource(cn.taketoday.aop.TargetSource) SingletonTargetSource(cn.taketoday.aop.target.SingletonTargetSource) ITestBean(cn.taketoday.beans.testfixture.beans.ITestBean) TestBean(cn.taketoday.beans.testfixture.beans.TestBean) DebugInterceptor(cn.taketoday.aop.interceptor.DebugInterceptor) FileNotFoundException(java.io.FileNotFoundException) SQLException(java.sql.SQLException) MarshalException(java.rmi.MarshalException) Assertions.assertThatIllegalStateException(org.assertj.core.api.Assertions.assertThatIllegalStateException) IOException(java.io.IOException) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException) LockedException(test.mixin.LockedException) Assertions.assertThatIllegalArgumentException(org.assertj.core.api.Assertions.assertThatIllegalArgumentException) Test(org.junit.jupiter.api.Test)

Example 10 with TargetSource

use of cn.taketoday.aop.TargetSource in project today-framework by TAKETODAY.

the class ContextAnnotationAutowireCandidateResolver method buildLazyResolutionProxy.

protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, @Nullable final String beanName) {
    BeanFactory beanFactory = getBeanFactory();
    Assert.state(beanFactory instanceof StandardBeanFactory, "BeanFactory needs to be a StandardBeanFactory");
    final StandardBeanFactory dlbf = (StandardBeanFactory) beanFactory;
    TargetSource ts = new TargetSource() {

        @Override
        public Class<?> getTargetClass() {
            return descriptor.getDependencyType();
        }

        @Override
        public boolean isStatic() {
            return false;
        }

        @Override
        public Object getTarget() {
            Set<String> autowiredBeanNames = beanName != null ? new LinkedHashSet<>(1) : null;
            Object target = dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, null);
            if (target == null) {
                Class<?> type = getTargetClass();
                if (Map.class == type) {
                    return Collections.emptyMap();
                } else if (List.class == type) {
                    return Collections.emptyList();
                } else if (Set.class == type || Collection.class == type) {
                    return Collections.emptySet();
                }
                throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(), "Optional dependency not present for lazy injection point");
            }
            if (autowiredBeanNames != null) {
                for (String autowiredBeanName : autowiredBeanNames) {
                    if (dlbf.containsBean(autowiredBeanName)) {
                        dlbf.registerDependentBean(autowiredBeanName, beanName);
                    }
                }
            }
            return target;
        }

        @Override
        public void releaseTarget(Object target) {
        }
    };
    ProxyFactory pf = new ProxyFactory();
    pf.setTargetSource(ts);
    Class<?> dependencyType = descriptor.getDependencyType();
    if (dependencyType.isInterface()) {
        pf.addInterface(dependencyType);
    }
    return pf.getProxy(dlbf.getBeanClassLoader());
}
Also used : TargetSource(cn.taketoday.aop.TargetSource) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) ProxyFactory(cn.taketoday.aop.framework.ProxyFactory) BeanFactory(cn.taketoday.beans.factory.BeanFactory) StandardBeanFactory(cn.taketoday.beans.factory.support.StandardBeanFactory) Collection(java.util.Collection) List(java.util.List) StandardBeanFactory(cn.taketoday.beans.factory.support.StandardBeanFactory) NoSuchBeanDefinitionException(cn.taketoday.beans.factory.NoSuchBeanDefinitionException)

Aggregations

TargetSource (cn.taketoday.aop.TargetSource)22 MethodInterceptor (org.aopalliance.intercept.MethodInterceptor)8 Test (org.junit.jupiter.api.Test)7 ProxyFactory (cn.taketoday.aop.framework.ProxyFactory)6 SingletonTargetSource (cn.taketoday.aop.target.SingletonTargetSource)6 StandardBeanFactory (cn.taketoday.beans.factory.support.StandardBeanFactory)4 AdvisedSupport (cn.taketoday.aop.framework.AdvisedSupport)3 DebugInterceptor (cn.taketoday.aop.interceptor.DebugInterceptor)3 HotSwappableTargetSource (cn.taketoday.aop.target.HotSwappableTargetSource)3 ITestBean (cn.taketoday.beans.testfixture.beans.ITestBean)3 TestBean (cn.taketoday.beans.testfixture.beans.TestBean)3 FileNotFoundException (java.io.FileNotFoundException)3 IOException (java.io.IOException)3 UndeclaredThrowableException (java.lang.reflect.UndeclaredThrowableException)3 MarshalException (java.rmi.MarshalException)3 SQLException (java.sql.SQLException)3 Assertions.assertThatIllegalArgumentException (org.assertj.core.api.Assertions.assertThatIllegalArgumentException)3 Assertions.assertThatIllegalStateException (org.assertj.core.api.Assertions.assertThatIllegalStateException)3 AopInvocationException (cn.taketoday.aop.AopInvocationException)2 AbstractLazyCreationTargetSource (cn.taketoday.aop.target.AbstractLazyCreationTargetSource)2