maven依賴中引用了consul的spring-cloud-starter-consul-discovery服務(wù)發(fā)現(xiàn)jar,導(dǎo)致@Controller注冊失效,訪問404,后來排查是動態(tài)代理導(dǎo)致的。
打印控制層代碼
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
@EnableDiscoveryClient
@SpringBootApplication
public class ComplaintApplication {
public static void main(String[] args) throws NoSuchMethodException,InstantiationException,IllegalAccessException, InvocationTargetException {
ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(ComplaintApplication.class, args);
String[] beans = configurableApplicationContext.getBeanDefinitionNames();
RequestMappingHandlerMapping requestMappingHandlerMapping=configurableApplicationContext.getBean(RequestMappingHandlerMapping.class);
// 獲取url與類和方法的對應(yīng)信息
Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
for (RequestMappingInfo info : map.keySet()) {
// 獲取url的Set集合,一個方法可能對應(yīng)多個url
Set<String> patterns = info.getPatternsCondition().getPatterns();
for (String url : patterns) {
//把結(jié)果存入靜態(tài)變量中程序運行一次次方法之后就不用再次請求次方法
System.out.println(url);
}
}
for (String bean : beans)
{
System.out.println(bean + " of Type :: " + configurableApplicationContext.getBean(bean).getClass());
}
}
}
userController打印出來的class 是class com.sun.proxy.$Proxy103

bean對象
解決辦法在yml文件添加配置就會去使用cglib的代理
spring:
aop:
auto: false
基于CGLIB的代理與基于JDK的動態(tài)代理實現(xiàn)的聲明式事務(wù)的區(qū)別
- CGLIB基于繼承實現(xiàn),JDK動態(tài)代理基于實現(xiàn)接口實現(xiàn)
- CGLIB的代理類需要事務(wù)注解@Transactional標(biāo)注在類上(或方法);而JDK動態(tài)代理類事務(wù)注解@Transactional可以標(biāo)注在接口上(或方法),也可以標(biāo)注在實現(xiàn)類上(或方法)
| auto | proxy-target-class | proxyTargetClass | 代理技術(shù) | 備注 |
|---|---|---|---|---|
| true | false | false | JDK動態(tài)代理 | |
| true | true | false | CGLIB | 默認(rèn)值 |
| true | false | true | CGLIB | |
| true | true | true | CGLIB | |
| false | false | false | JDK動態(tài)代理 | |
| false | true | false | JDK動態(tài)代理 | |
| false | false | true | CGLIB | |
| false | true | true | CGLIB |