Unverified Commit ee2f5c5e authored by 吴晟's avatar 吴晟 Committed by GitHub
Browse files

Merge pull request #595 from ascrutae/fix/spring-aop-issue

fix issue that controller cannot find the request mapping
parents d2df4db2 1c762f1c
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright 2017, OpenSkywalking Organization All rights reserved.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  ~
  ~ Project repository: https://github.com/OpenSkywalking/skywalking
  -->

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-plugins</artifactId>
        <groupId>org.skywalking</groupId>
        <version>3.2.5-2017</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>apm-spring-core-patch</artifactId>
    <name>core-patch</name>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>3.2.9.RELEASE</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017, OpenSkywalking Organization All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Project repository: https://github.com/OpenSkywalking/skywalking
 */

package org.skywalking.apm.plugin.spring.patch;

import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.springframework.aop.framework.AdvisedSupport;

/**
 * {@link CreateAopProxyInterceptor} check that the bean has been implement {@link EnhancedInstance}. <p/>
 * if yes, true will be returned.
 *
 * @author zhang xin
 */
public class CreateAopProxyInterceptor implements InstanceMethodsAroundInterceptor {

    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        MethodInterceptResult result) throws Throwable {

    }

    @Override
    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        Object ret) throws Throwable {
        AdvisedSupport advisedSupport = (AdvisedSupport)allArguments[0];

        if (EnhancedInstance.class.isAssignableFrom(advisedSupport.getTargetClass())) {
            return true;
        }
        return ret;
    }

    @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
        Class<?>[] argumentsTypes, Throwable t) {

    }
}
+70 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017, OpenSkywalking Organization All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Project repository: https://github.com/OpenSkywalking/skywalking
 */

package org.skywalking.apm.plugin.spring.patch.define;

import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;

import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;

/**
 * {@link AopProxyFactoryInstrumentation} indicate that spring core patch plugin intercepts the {@link
 * org.springframework.aop.framework.DefaultAopProxyFactory#hasNoUserSuppliedProxyInterfaces} method by using {@link
 * org.skywalking.apm.plugin.spring.patch.CreateAopProxyInterceptor} class.
 *
 * @author zhangxin
 */
public class AopProxyFactoryInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

    private static final String ENHANCE_CLASS = "org.springframework.aop.framework.DefaultAopProxyFactory";
    public static final String ENHANCE_METHOD = "hasNoUserSuppliedProxyInterfaces";
    public static final String INTERCEPT_CLASS = "org.skywalking.apm.plugin.spring.patch.CreateAopProxyInterceptor";

    @Override protected final ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
        return new ConstructorInterceptPoint[0];
    }

    @Override protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[] {
            new InstanceMethodsInterceptPoint() {
                @Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
                    return named(ENHANCE_METHOD);
                }

                @Override public String getMethodsInterceptor() {
                    return INTERCEPT_CLASS;
                }

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

    @Override protected ClassMatch enhanceClass() {
        return byName(ENHANCE_CLASS);
    }

}
+1 −0
Original line number Diff line number Diff line
spring-core-patch=org.skywalking.apm.plugin.spring.patch.define.AopProxyFactoryInstrumentation
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017, OpenSkywalking Organization All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Project repository: https://github.com/OpenSkywalking/skywalking
 */

package org.skywalking.apm.plugin.spring.patch;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.springframework.aop.framework.AdvisedSupport;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.doReturn;

@RunWith(MockitoJUnitRunner.class)
public class CreateAopProxyInterceptorTest {

    private CreateAopProxyInterceptor interceptor;

    @Mock
    private EnhancedInstance enhancedInstance;

    @Mock
    private AdvisedSupport advisedSupport;

    @Before
    public void setUp() {
        interceptor = new CreateAopProxyInterceptor();

    }

    @Test
    public void testInterceptNormalObject() throws Throwable {
        doReturn(Object.class).when(advisedSupport).getTargetClass();
        assertThat(false, is(interceptor.afterMethod(enhancedInstance, null, new Object[] {advisedSupport}, new Class[] {Object.class}, false)));
    }

    @Test
    public void testInterceptEnhanceInstanceObject() throws Throwable {
        doReturn(MockClass.class).when(advisedSupport).getTargetClass();
        assertThat(true, is(interceptor.afterMethod(enhancedInstance, null, new Object[] {advisedSupport}, new Class[] {Object.class}, false)));
    }

    private class MockClass implements EnhancedInstance {

        @Override public Object getSkyWalkingDynamicField() {
            return null;
        }

        @Override public void setSkyWalkingDynamicField(Object value) {

        }
    }

}
Loading