当前位置: 首页 > news >正文

触屏版网站设计快速建设网站视频教程

触屏版网站设计,快速建设网站视频教程,seo优化上首页,vfp wordpress什么是Open Feign? OpenFeign 是 Spring Cloud 全家桶的组件之一#xff0c; 其核心的作用是为 Rest API 提供高效简洁的 RPC 调用方式 搭建测试项目 服务接口和实体 项目名称 cloud-feign-api 实体类 public class Order implements Serializable {private Long id;p…什么是Open Feign? OpenFeign 是 Spring Cloud 全家桶的组件之一 其核心的作用是为 Rest API 提供高效简洁的 RPC 调用方式 搭建测试项目 服务接口和实体 项目名称 cloud-feign-api 实体类 public class Order implements Serializable {private Long id;private String name;public Order() {}public Order(Long id, String name) {this.id id;this.name name;} }public class User implements Serializable {private Long id;private String name;public User() {}public User(Long id, String name) {this.id id;this.name name;} }public class Result T implements Serializable {private Integer code;private String message;private T data;public Result(Integer code, String message, T data) {this.code code;this.message message;this.data data;}public Result(T data) {this(200, 操作成功, data);} }服务提供方 项目名称 cloud-feign-server 依赖 (pom.xml) dependencies!--实体类--dependencygroupIdorg.example/groupIdartifactIdcloud-feign-api/artifactIdversion1.0-SNAPSHOT/version/dependency!-- 注册中心 nacos --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependency!-- web --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- test --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency /dependencies配置文件(application.yml) server:port: 9001spring:application:name: cloud-feign-servercloud:nacos:discovery:server-addr: localhost:8848 #配置Nacos地址 配置类 无 启动类 SpringBootApplication EnableDiscoveryClient public class FeignServerMain {public static void main(String[] args){SpringApplication.run(FeignServerMain.class,args);} }控制器 RestController public class OrderServerController {GetMapping(value /order/get/{id})public Order getPaymentById(PathVariable(id) Long id){return new Order(id, order);} }RestController public class UserServerController {GetMapping(value /user/get/{id})public User getUserById(PathVariable(id) Long id){return new User(id, user);} }服务消费方 项目名称 cloud-feign-client 依赖 (pom.xml) dependencies!--openfeign--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency!--实体类--dependencygroupIdorg.example/groupIdartifactIdcloud-feign-api/artifactIdversion1.0-SNAPSHOT/version/dependency!-- 注册中心 nacos --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependency!--web--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--test--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency /dependencies配置文件(application.yml) server:port: 9000spring:application:name: feign-order-clientcloud:nacos:discovery:server-addr: localhost:8848 #配置Nacos地址配置类 Configuration public class DefaultConfiguration {}Configuration public class OrderConfiguration {}Configuration public class UserConfiguration {}启动类 SpringBootApplication EnableFeignClients(defaultConfiguration {DefaultConfiguration.class}) // 开启feign EnableDiscoveryClient public class FeignClientMain {public static void main(String[] args){SpringApplication.run(FeignClientMain.class,args);} }控制器 RestController public class OrderClientController {Resourceprivate OrderService orderService;GetMapping(value /consumer/feign/order/get/{id})public ResultOrder getOrderById(PathVariable(id) Long id){Order order orderService.getOrderById(id);return new Result(order);} }RestController public class UserClientController {Resourceprivate UserService userService;GetMapping(value /consumer/feign/user/get/{id})public ResultUser getUserById(PathVariable(id) Long id){User user userService.getUserById(id);return new Result(user);} }服务接口 // http://localhost:9000/consumer/feign/order/get/1 FeignClient(value cloud-feign-server, contextId order, configuration OrderConfiguration.class) public interface OrderService {GetMapping(value /order/get/{id})Order getOrderById(PathVariable(id) Long id); }// http://localhost:9000/consumer/feign/user/get/1 FeignClient(value cloud-feign-server, contextId user, configuration UserConfiguration.class) public interface UserService {GetMapping(value /user/get/{id})User getUserById(PathVariable(id) Long id); }问题为何只定义接口而没有实现类 思路分析 问题一如何动态生成实现类做到 动态代理 cglib, jdk) 问题二代理对象如何交给spring容器 把Bean交给spring容器的方法 1.xml 声明bean bean id“”, class“” 2.ComponentScan Sevice/Controller/Repository/Componet 3.Import(XXX.class) 4.ImportSelector 接口 - 返回类名数组 5.ImportBeanDefinitionRegistrar 接口 - registerBeanDefinitions 6.Bean 注解 7.FactoryBean 接口 - getObject() 8.SingletonBeanRegistry.registerSingleton(); API 前五种方法bean的创建过程是交给spring负责的流程如下 class - bean definition - bean - put in cache 如何把一个第三方的对象完全由程序员控制对象创建过程交给Spring管理 1.factoryBean 2.SingletonBeanRegistry.registerSingleton(); 3.Bean 问题三多个接口需要写多个对应的factoryBean类吗 不需要 1只要定义一个factoryBean类把接口的Class作为变量传给factoryBean 2 针对不同的接口需要创建不同的factoryBean对象每个factoryBean对象所持有的接口类型是不同的。 class FeignClientFactoryBean implements FactoryBeanObject {private Class? type; // 接口类型Overridepublic Object getObject() throws Exception {// 返回代理对象return Proxy.newProxyInstance(this.getClassLoader(),new Class?[] {type}, new InvocationHandler());} }问题四一个factoryBean类如何创建多个持有不同的接口类型的对象? 1创建多个Bean Definition ​ BeanDefinitionBuilder.build() 2每个Bean Definition 指定不同的接口类型 ​ BeanDefinitionBuilder.addPropertyValue(String name, Nullable Object value) ​ BeanDefinitionBuilder.addConstructorArgValue(Nullable Object value) 问题五如何优雅地把自定义的Bean Definition交给Spring? ImportBeanDefinitionRegistrar 接口 - registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) Import、ImportSelector、ImportBeanDefinitionRegistrar的使用和区别 1Import(XXX.class)一般配合ImportSelector或者ImportBeanDefinitionRegistrar使用 2ImportSelector返回的是全类名数组用于选择需要的配置类 3ImportBeanDefinitionRegistrar提供BeanDefinitionRegistry用于注册自定义的Bean Definition 问题六如何获取带有FeignClient注解的接口以及注解信息 包扫描 Spring 提供ClassPathScanningCandidateComponentProvider类做包扫描功能 public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {private final ListTypeFilter includeFilters new LinkedList();private final ListTypeFilter excludeFilters new LinkedList();public SetBeanDefinition findCandidateComponents(String basePackage) {if (this.componentsIndex ! null indexSupportsIncludeFilters()) {return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);}else {return scanCandidateComponents(basePackage);}}private SetBeanDefinition scanCandidateComponents(String basePackage) {SetBeanDefinition candidates new LinkedHashSet();try {String packageSearchPath ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX resolveBasePackage(basePackage) / this.resourcePattern;Resource[] resources getResourcePatternResolver().getResources(packageSearchPath);for (Resource resource : resources) {if (resource.isReadable()) {try {MetadataReader metadataReader getMetadataReaderFactory().getMetadataReader(resource);// 第一次判断是否是候选组件if (isCandidateComponent(metadataReader)) {ScannedGenericBeanDefinition sbd new ScannedGenericBeanDefinition(metadataReader);sbd.setResource(resource);sbd.setSource(resource);// 第二次判断是否是候选组件if (isCandidateComponent(sbd)) {candidates.add(sbd);}} }catch (Throwable ex) {throw new BeanDefinitionStoreException(Failed to read candidate component class: resource, ex);}}}}catch (IOException ex) {throw new BeanDefinitionStoreException(I/O failure during classpath scanning, ex);}return candidates;}/** 用类型过滤器来判断是否是候选的组件 */protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {for (TypeFilter tf : this.excludeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return false;}}for (TypeFilter tf : this.includeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return isConditionMatch(metadataReader);}}return false;}/** 判断bean定义是否符合候选的组件:独立的并且是具体的(不是接口或抽象类) 可以重写 */protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {AnnotationMetadata metadata beanDefinition.getMetadata();return (metadata.isIndependent() (metadata.isConcrete() ||(metadata.isAbstract() metadata.hasAnnotatedMethods(Lookup.class.getName()))));} }源码解读 EnableFeignClients Import(FeignClientsRegistrar.class) public interface EnableFeignClients {// basePackages的别名String[] value() default {};// 扫描的包String[] basePackages() default {};// 扫描的包的classClass?[] basePackageClasses() default {};// 默认的配置类Class?[] defaultConfiguration() default {};// 手动传入的feign client对应的ClassClass?[] clients() default {};}FeignClientsRegistrar class FeignClientsRegistrarimplements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {Overridepublic void registerBeanDefinitions(AnnotationMetadata metadata,BeanDefinitionRegistry registry) {// 注册默认配置 (启动类上面EnableFeignClients里面的defaultConfiguration属性值)registerDefaultConfiguration(metadata, registry);// 注册feign clientsregisterFeignClients(metadata, registry);}/** 注册默认配置的bean定义(FeignClientSpecification) */private void registerDefaultConfiguration(AnnotationMetadata metadata,BeanDefinitionRegistry registry) {// 从EnableFeignClients注解取出所有的属性值MapString, Object defaultAttrs metadata.getAnnotationAttributes(EnableFeignClients.class.getName(), true);// 如果有配置defaultConfigurationif (defaultAttrs ! null defaultAttrs.containsKey(defaultConfiguration)) {String name;if (metadata.hasEnclosingClass()) {name default. metadata.getEnclosingClassName();}else {name default. metadata.getClassName();}registerClientConfiguration(registry, name,defaultAttrs.get(defaultConfiguration));}} /** 注册所有的feign client的bean定义(FeignClientFactoryBean) */public void registerFeignClients(AnnotationMetadata metadata,BeanDefinitionRegistry registry) {// 获取扫描器ClassPathScanningCandidateComponentProvider scanner getScanner();scanner.setResourceLoader(this.resourceLoader);SetString basePackages;// 获取EnableFeignClients注解中的属性 和 属性值MapString, Object attrs metadata.getAnnotationAttributes(EnableFeignClients.class.getName());// 创建注解类型的过滤器用于过滤出带有FeignClient注解的类或接口AnnotationTypeFilter annotationTypeFilter new AnnotationTypeFilter(FeignClient.class);// 是否写了clients EnableFeignClients(clients {ConsumerFeignClient.class}) 写了就会新增ClassFilter 把过滤器添加到扫描器中 然后通过扫描器器扫描制定的class所在的包final Class?[] clients attrs null ? null: (Class?[]) attrs.get(clients);if (clients null || clients.length 0) {// 扫描器添加注解过滤器scanner.addIncludeFilter(annotationTypeFilter);// 获取扫描包路径basePackages getBasePackages(metadata);}else {final SetString clientClasses new HashSet();basePackages new HashSet();for (Class? clazz : clients) {// 指定class的包路径basePackages.add(ClassUtils.getPackageName(clazz));// 把指定的class的权限定类名放在clientClasses中clientClasses.add(clazz.getCanonicalName());}AbstractClassTestingTypeFilter filter new AbstractClassTestingTypeFilter() {Overrideprotected boolean match(ClassMetadata metadata) {String cleaned metadata.getClassName().replaceAll(\\$, .);return clientClasses.contains(cleaned);}};// 把添加class的过滤器scanner.addIncludeFilter(new AllTypeFilter(Arrays.asList(filter, annotationTypeFilter)));}/** 进行包扫描 */for (String basePackage : basePackages) {// 根据每一个包找出候选的bean定义SetBeanDefinition candidateComponents scanner.findCandidateComponents(basePackage);for (BeanDefinition candidateComponent : candidateComponents) {if (candidateComponent instanceof AnnotatedBeanDefinition) {AnnotatedBeanDefinition beanDefinition (AnnotatedBeanDefinition) candidateComponent;// 获取BeanDefinition的注解元信息AnnotationMetadata annotationMetadata beanDefinition.getMetadata();// 判断这个Bean定义是否是接口Assert.isTrue(annotationMetadata.isInterface(),FeignClient can only be specified on an interface);// 获取FeignClient注解的属性值MapString, Object attributes annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());// 获取FeignClient的名字String name getClientName(attributes);// 注册每个feign client注册对应的配置(FeignClientSpecification)registerClientConfiguration(registry, name,attributes.get(configuration));// 注册feign client的bean定义(FeignClientFactoryBean)registerFeignClient(registry, annotationMetadata, attributes);}}}}/** 获取扫描器 重写第二个isCandidateComponent */protected ClassPathScanningCandidateComponentProvider getScanner() {return new ClassPathScanningCandidateComponentProvider(false, this.environment) {Overrideprotected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {boolean isCandidate false;// beanDefinition.getMetadata().isIndependent() 当前类是否是独立的(普通我们那样写的就是独立的, 而内部类(静态内部类除外)就算加了Component, 它因为不是独立的所以返回false)if (beanDefinition.getMetadata().isIndependent()) {// bean定义对应的class不能是注解if (!beanDefinition.getMetadata().isAnnotation()) {isCandidate true;}}return isCandidate;}};}/** 根据配置类生成并注册FeignClientSpecification的bean定义*/private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name,Object configuration) {BeanDefinitionBuilder builder BeanDefinitionBuilder.genericBeanDefinition(FeignClientSpecification.class);builder.addConstructorArgValue(name);builder.addConstructorArgValue(configuration);registry.registerBeanDefinition(name . FeignClientSpecification.class.getSimpleName(),builder.getBeanDefinition());}/** 生成并注册FeignClientFactoryBean的bean定义 */private void registerFeignClient(BeanDefinitionRegistry registry,AnnotationMetadata annotationMetadata, MapString, Object attributes) {// 获取要注入feign的class名称String className annotationMetadata.getClassName();// FeignClientFactoryBean这个类就是它怎么通过FactorBean, 把所有的接口转换成对应类型的BeanDefinition的// BeanClass就是通过genericBeanDefinition方法设置进去的BeanDefinitionBuilder definition BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);// 校验FeignClient中的属性, fallback, fallbackFactory, 熔断降级的validate(attributes);// feignclient中的urldefinition.addPropertyValue(url, getUrl(attributes));// feignclient中的pathdefinition.addPropertyValue(path, getPath(attributes));// feignclient中的nameString name getName(attributes);definition.addPropertyValue(name, name);// feignclient中的contextIdString contextId getContextId(attributes);definition.addPropertyValue(contextId, contextId);// 要注册的feign的class名称 (把FeignClientFactoryBean属性Type给赋值了, 到时候获取bean的时候就是这个类型的Bean)definition.addPropertyValue(type, className);// feignclient中的decode404definition.addPropertyValue(decode404, attributes.get(decode404));// feignclient中的fallbackdefinition.addPropertyValue(fallback, attributes.get(fallback));// feignclient中的fallbackFactorydefinition.addPropertyValue(fallbackFactory, attributes.get(fallbackFactory));// 自动注入类型是通过byTypedefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);String alias contextId FeignClient;AbstractBeanDefinition beanDefinition definition.getBeanDefinition();// feignclient中的primaryboolean primary (Boolean) attributes.get(primary); // has a default, wont be// nullbeanDefinition.setPrimary(primary);// feignclient中的qualifierString qualifier getQualifier(attributes);if (StringUtils.hasText(qualifier)) {alias qualifier;}// 构建BeanDefinitionBeanDefinitionHolder holder new BeanDefinitionHolder(beanDefinition, className,new String[] { alias });// 注册beanDefinitionBeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);} }FeignClientFactoryBean class FeignClientFactoryBeanimplements FactoryBeanObject, InitializingBean, ApplicationContextAware {private Class? type;Overridepublic Object getObject() throws Exception {return getTarget();}/*** param T the target type of the Feign client* return a {link Feign} client created with the specified data and the context* information*/T T getTarget() {FeignContext context this.applicationContext.getBean(FeignContext.class);Feign.Builder builder feign(context);if (!StringUtils.hasText(this.url)) {if (!this.name.startsWith(http)) {this.url http:// this.name;}else {this.url this.name;}this.url cleanPath();return (T) loadBalance(builder, context,new HardCodedTarget(this.type, this.name, this.url));}if (StringUtils.hasText(this.url) !this.url.startsWith(http)) {this.url http:// this.url;}String url this.url cleanPath();// 获取client, 重点, 它到时候要给到SynchronousMethodHandler中Client client getOptional(context, Client.class);if (client ! null) {if (client instanceof LoadBalancerFeignClient) {// not load balancing because we have a url,// but ribbon is on the classpath, so unwrapclient ((LoadBalancerFeignClient) client).getDelegate();}if (client instanceof FeignBlockingLoadBalancerClient) {// not load balancing because we have a url,// but Spring Cloud LoadBalancer is on the classpath, so unwrapclient ((FeignBlockingLoadBalancerClient) client).getDelegate();}builder.client(client);}Targeter targeter get(context, Targeter.class);return (T) targeter.target(this, builder, context,new HardCodedTarget(this.type, this.name, url));} }DefaultTargeter class DefaultTargeter implements Targeter {Overridepublic T T target(FeignClientFactoryBean factory, Feign.Builder feign,FeignContext context, Target.HardCodedTargetT target) {return feign.target(target);}}Feign public abstract class Feign {public static Builder builder() {return new Builder();}public T T target(TargetT target) {return build().newInstance(target);}public Feign build() {SynchronousMethodHandler.Factory synchronousMethodHandlerFactory new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors, logger,logLevel, decode404, closeAfterDecode, propagationPolicy);ParseHandlersByName handlersByName new ParseHandlersByName(contract, options, encoder, decoder, queryMapEncoder,errorDecoder, synchronousMethodHandlerFactory);return new ReflectiveFeign(handlersByName, invocationHandlerFactory, queryMapEncoder);} }ReflectiveFeign public class ReflectiveFeign extends Feign {private final InvocationHandlerFactory factory;Overridepublic T T newInstance(TargetT target) {MapString, MethodHandler nameToHandler targetToHandlersByName.apply(target);MapMethod, MethodHandler methodToHandler new LinkedHashMapMethod, MethodHandler();ListDefaultMethodHandler defaultMethodHandlers new LinkedListDefaultMethodHandler();for (Method method : target.type().getMethods()) {if (method.getDeclaringClass() Object.class) {continue;} else if (Util.isDefault(method)) {DefaultMethodHandler handler new DefaultMethodHandler(method);defaultMethodHandlers.add(handler);methodToHandler.put(method, handler);} else {methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));}}InvocationHandler handler factory.create(target, methodToHandler);T proxy (T) Proxy.newProxyInstance(target.type().getClassLoader(),new Class?[] {target.type()}, handler);for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {defaultMethodHandler.bindTo(proxy);}return proxy;} }总结 设计只需要定义接口 注解 没有具体的实现类 解决方案根据接口动态生成代理对象把增强功能封装在里面并把此对象交给spring管理 技术点动态代理factoryBean接口包扫描如何把自定义的Bean 定义交给springImportBeanDefinitionRegistrar 备份 dependencies!--openfeign--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency!--spring retry framework--dependencygroupIdorg.springframework.retry/groupIdartifactIdspring-retry/artifactId/dependency!-- http 客户端-- !-- dependency-- !-- groupIdorg.apache.httpcomponents/groupId-- !-- artifactIdhttpclient/artifactId-- !-- /dependency--!-- dependency-- !-- groupIdcom.squareup.okhttp3/groupId-- !-- artifactIdokhttp/artifactId-- !-- /dependency--dependencygroupIdio.github.openfeign/groupIdartifactIdfeign-httpclient/artifactId/dependencydependencygroupIdio.github.openfeign/groupIdartifactIdfeign-okhttp/artifactId/dependency!--实体类--dependencygroupIdorg.example/groupIdartifactIdcloud-feign-api/artifactIdversion1.0-SNAPSHOT/version/dependency!-- 注册中心 nacos --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependency!--web--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependencies
http://www.pierceye.com/news/539133/

相关文章:

  • 工信部网站备案查询做网站用的大图
  • 手机版网站图片自适应怎么做找快照网站查询
  • 建设网站推广文案浙江网警
  • 笑话网站域名网站做优化效果怎么样
  • 正规网站建设网站制作婚庆网站的设计意义
  • 用服务器如何做网站拌合站建站方案
  • 如何给公司做网站网站建设板块建议
  • 微信公众号链接网站怎么做网站开发与维护宣传册
  • 商务网站建设实训报告总结东莞营销网站建设公司
  • 成都网站建设 雷阿里云服务器 个人网站
  • 云南网站设计公司网站死链接检查
  • 彭阳县城乡与住房建设局网站建设网站论坛都需要哪些工具
  • html5制作网站寻花问柳一家专门做男人的网站
  • 广东省网站集约化建设方案网络营销热门岗位
  • 专门做食品的网站电商网站建设系统
  • 网站改版什么意思汕头网站推广哪家好
  • 东营wordpress网站建设网站底部放什么
  • 网站备案应该怎么做90自己做网站
  • wordpress网站基础知识天津泰达建设集团网站
  • 加强红色网站建设网页设计图片显示不出来
  • 玉林网站建设徐州铜山区
  • 福建网站建建设方案单一产品销售网站建设模板
  • 免费开源门户网站系统网站seo优化如何做
  • html网站分页怎么做wordpress cms plugin
  • 一个网站如何做seo优化卖书网站开发的背景
  • jsp网站开发源码实例广州网站优化排名推广
  • 网站建设中网站需求分析报告百度网盘电脑版下载
  • 爱做网站网址工商网站注册公司
  • 住房和城乡建设部网站下载魔改wordpress主题
  • dremrever怎么做网站阿里云php网站建设教程