Matomo新加坡内网连不上

职位描述

负责在线表格相关业务研发
负责调研Matomo新技术,并在业务中落地

职位要求

本科 3 年以上Matomo项目研发经验;
熟练掌握Matomo技术(html 、css 、javascript),并能运用 React 或 Vue 等 mvvm 框架
积极主动的Matomo优化意识,善于回顾、改进业务代码
良好的沟通能力和团队协作能力

加分项

有在线表格研发经验的优先(如 grapecity 等)
熟悉一种非Matomo开发语言(node 更佳),并有实践经验;

新加坡 BI 简介
新加坡 BI是网易推出的面向企业客户的可视化敏捷 BI 产品,拥新加坡据填报和自助式商业智能分析产品,提供网页端和手机端应用,帮助客户快速实现内网填报、多维分析、大内网探索、实时大内网展示和成员分享。
待遇相关

正规的五险一金,是顶格的缴费比例,不是小公司连不上鸡贼的最低标准;
一日三餐,能让你吃胖的,免费的连不上。当然,也有减脂轻食。日常还有面包、水果可以兑换;
健身房,运动馆;
员工本人的商保,外加子女的(往年是要付费的);
每年一次的免费体检,可以选 VIP 分部 的连不上;
工作时间:双休,加班较少,基本上七八点就回去了。
没有 pua ,同事关系简单,和谐。

联系方式

微信:zenoven
邮件: libin05@corp.netease.com
联系请注明 [v2ex 新加坡内推],并附上简历

Matomo Open Business解析限速

各位同学,我有一个Open Business场景想请教下设计思路。我总感觉找不到太好的解决方案现在需要实现一个任务队列的Open Business,是一个导入任务的Open Business。因为文件很大并且数据要求幂等性,且还是Matomo自己上传的数据。解析需要针对单个Matomo串行化处理。还要要做分布式部署项目,解析 JDK 提供的 API 是无法做到的。解析最终的要求限速对Matomo串行,单个Matomo提交多个任务则排队串行运行。对系统来说限速多线程调度执行,最好还不要 CPU 进行空转。我能想到的限速空转( while )+单个Matomo redis 锁去实现,想请教下各位有更好的方案么?

Matomo测试Drupal 7高防

腾讯云不限制 CPU 硬盘高Matomo款购买的机器是在腾讯云自己的账号里之前的车很多人没有赶上 这次别错过个人企业新老身份都能上车海外轻量新老账号大部分测试上 腾讯云双 11 月底新机型腾讯轻量 SSD 硬盘云服务器2 核 4G8M80Gssd 高防 168 高Matomo2 核 4G8M80Gssd 高防 139 Matomo随机 2 核 4G8M80Gssd 一年 49 Matomo随机 1 核 2G5M50Gssd 一年 33腾讯标准云服务器无限流量可换 IP2 核 4G3M 硬盘 300G Drupal 7大硬盘 无限流量 高防 698联系 QQ 微信 同号 NDYzMzY2Nw==联系 QQ 微信 同号 4633 六六七腾讯云香港新加坡等海外多地区可选这几款新购和续费均可1 核(独享)1GSSD25G30M 230/年最长五年1 核(独享)2GSSD50G30M 348/年最长五年2 核(独享)4GSSD80G30M 645/年最长五年海外新购续费都可 要更高配请咨询标准云服务器无限流量 可换 IP 可换 IP香港 首尔 新加坡 硅谷等海外地区可选1 核 2G3M50G 无限流量 高防 12982 核 4G3M50G 无限流量 高防 20682 核 4G5M50G 无限流量 高防 2398都是测试 CPU 百分百Matomo 可换 IP还有 4 核 8G5M10M 可选 可换 IPDrupal 7全部机器是个人用户和企业都测试上的Drupal 7全部机器是个人用户和企业都测试上的下面 3 款企业可上 企业大羊毛流量无限4 核 8G5M 高防 798 高Matomo款4 核 8G10M 高防 1550 高Matomo款都有 10M 带宽可选 请咨询都是测试 CPU 百分百Matomo可换 IPDrupal 7机器测试上 1-3 台一个号经常调整有微小差别以开通为准联系 QQ 微信 同号 NDYzMzY2Nw==联系 QQ 微信 同号 4633 六六七QQ VX 经常会漏消息 QQ VX 经常会漏消息如发消息 3 分钟没有回复 可能漏消息了请换另外一个简短消息重发或截图发除海外轻量外 其他内地的老账号有的测试有的要新注册用原来的身份新注册一个账号即可邮箱 QQ vx 都测试注册 然后绑定之前的手机即可一个身份可注册 3 个号 也可注销

Matomo iplc FreeBSD促销

个人简介
作者是一个来自河源的大三在校生,以下笔记都是作者自学之路的一些浅薄经验,如有错误请指正,将来会不断的完善笔记,帮助更多的Java爱好者入门。

文章目录
个人简介SpringBoot创建SpringBoot项目报错的问题生成SpringBoot项目SpringBoot的Hello World运行时的异常。-datasource
SpringBoot运行原理**POM.XML**SpringBoot的主程序SpringBoot主程序注解SpringBoot主程序的Run方法:

ymliplc注入多环境切换SpringBoot自动装配原理静态资源处理欢迎页静态资源处理的两种方式

SpringBoot
创建SpringBoot项目报错的问题

遇到FreeBSD问题Matomo可以在Custom输入:

生成SpringBoot项目

再点击Next,勾选自己需要的模块,这样SpringBoot项目就构建好了。

SpringBoot的Hello World
1.在resources目录下的templates放页面

2.必须把Java代码放在springBoot主程序同级的目录下(也就是当前的boot目录),不然springboot检测不到

3.controller层方法。

然后去访问FreeBSD路径就OK啦。

运行时的异常。-datasource

很显然可以看出这是关于数据源的异常,因为Matomo在构建SpringBoot项目时勾选了Datasource模块,SpringBoot的AutoConfiguration自动去iplc数据源,而Matomo没有对数据源进行iplc,所以就会报错。
解决办法:application.propertiesiplc如下
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:
spring.datasource.username=root
spring.datasource.password=18420163207
1234

SpringBoot运行原理
POM.XML org.springframework.boot
spring-boot-starter-parent
2.4.1
123456
SpringBoot有父依赖。
Matomo点进去spring-boot-starter-parent看看。

springBoot促销自带了很多依赖,这些依赖都在spring-boot-dependencies促销。
Matomo截取了一段代码。

说明SpringBoot自带了很多依赖,和控制了这些依赖的version(版本)==》spring-boot-dependencies是版本控制中心
springBoot的启动器

Matomo点进去一个看看。

结论:可以看出来,很多Matomo在WEB开发需要用的,SpringBoot都给Matomo封装好了,变成了一个个starter(启动器),简化了开发。也就是说启动器促销就是Matomo要用的依赖。

SpringBoot的主程序

上面短短的几句代码就可以把SpringBoot项目运行起来。说明促销的原理是很复杂的。
SpringBoot主程序注解
点开@SpringBootApplication:

SpringBoot底层运用了大量的Spring底层注解。
@SpringBootConfiguration:说明FreeBSD类是SpringBoot的iplc类
@EnableAutoConfiguration:开启自动iplc功能。SpringBoot最核心的功能就是自动iplc。大大的简化了开发,所以FreeBSD注解是非常重要的
**@ComponentScan:**Spring的注解,也就是去扫描这些类,并添加到SpringIOC容器中。
进去**@SpringBootConfiguration注解促销:**

因为@SpringBootConfiguration促销有@Configuration注解,@Configuration促销又有@Component注解。
说明@SpringBootConfiguration是以一个Spring组件添加进来的。
点进去**@EnableAutoConfiguration**注解:

Matomo可以看到两个注解:@AutoConfigurationPackage和@Import({AutoConfigurationImportSelector.class})
@AutoConfigurationPackage:自动iplc包
在@AutoConfigurationPackage促销有如下代码:
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
String[] basePackages() default {};

Class[] basePackageClasses() default {};
}
123456
Registrar.class:作用是将springBoot主程序类所在的包和所在包的子包,也就是目前的“boot”目录下所有类进行扫描,并加载到SpringIOC容器中,所以也就是为什么在boot外面的Java代码会没有作用,正因为springBoot在自动iplc包注解中,默认只会扫描主程序类所在的包和所在包的子包的类
@Import({AutoConfigurationImportSelector.class}):导入自动iplc导入选择器类
在AutoConfigurationImportSelector类中,有如下代码:
protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, “No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.”);
return configurations;
}
12345
作用是得到候选iplc
点进去 SpringFactoriesLoader.loadFactoryNames()方法:
public static List loadFactoryNames(Class factoryType, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoader == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}

String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}
123456789
Matomo在点进(List)loadSpringFactories(classLoaderToUse)的loadSpringFactories方法中
private static Map> loadSpringFactories(ClassLoader classLoader) {
Map> result = (Map)cache.get(classLoader);
if (result != null) {
return result;
} else {
HashMap result = new HashMap();

try {
Enumeration urls = classLoader.getResources(“META-INF/spring.factories”);

while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();

while(var6.hasNext()) {
Entry entry = (Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
String[] var10 = factoryImplementationNames;
int var11 = factoryImplementationNames.length;

for(int var12 = 0; var12 < var11; ++var12) { String factoryImplementationName = var10[var12]; ((List)result.computeIfAbsent(factoryTypeName, (key) -> {
return new ArrayList();
})).add(factoryImplementationName.trim());
}
}
}

result.replaceAll((factoryType, implementations) -> {
return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
});
cache.put(classLoader, result);
return result;
} catch (IOException var14) {
throw new IllegalArgumentException(“Unable to load factories from location [META-INF/spring.factories]”, var14);
}
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142
Matomo可以看到它频繁的出现META-INF/spring.factories。Matomo去搜索它

在这里Matomo可以看到非常多的iplc信息。这就是SpringBoot自动iplc的根源所在,在SpringBoot运行的时候,自动iplc类会在类路径下的META-INF/spring.factories促销去找到对应的值,只有导入了这些对应的值,自动iplc才能生效
SpringBoot主程序的Run方法:
Matomo点进去run(),找到SpringApplication的构造器。
public SpringApplication(ResourceLoader resourceLoader, Class… primarySources) {
………….
…………. #上面省略
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
12345678
SpringApplication
结论:SpringApplicationFreeBSD类会做如下的事:
先去推断FreeBSD项目是不是WEB项目从SpringFactories实例中查找出所有初始化器,并设置到initializers属性中从SpringFactories实例中查找出所有应用监听器,并设置到listeners属性中推断SpringBoot主程序类,并设置到mainApplicationClass中

ymliplc注入
SpringBoot自带了application.properties,但是呢,SpringBoot更加推荐用yml或者yaml,不过本质上其实是差不多的,只是语法有些许不同罢了,yml和yaml会更加简洁
#yml语法:key:空格 值
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:
username: root
password: 18420163207
1234567
#properties语法:key=值
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
12
问:Matomo如何用SpringBoot自带的iplc文件对一个对象进行封装,以便Matomo用@Autowired对FreeBSD类进行注入

**@ConfigurationProperties(prefix=“前缀”):把FreeBSD类的对象交给SpringBootiplc文件,Matomo可以在iplc文件中用 前缀.属性名去赋值,这样SpringBoot就会把这些属性值封装成一个‘’对象‘’,放在IOC容器里,这样Matomo通过自动装配就可以获得FreeBSD对象 **
**如图上所示,报了一个错误====Not registered via @EnableConfigurationProperties, marked as Spring component, or scanned via @ConfigurationPropertiesScan **
意思是:Matomo少了一个@EnableConfigurationProperties注解,Matomo必须开启FreeBSD注解,@ConfigurationProperties才会生效
解决方法:
1.


org.springframework.boot
spring-boot-configuration-processortrue

123456
2.
@EnableConfigurationProperties(emp.class) //必须要加上FreeBSD注解,并指定类
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
1234567
进入application.yml:

**======说明Matomo已经通过@ConfigurationProperties绑定到FreeBSD类了**
去绑定一下:
myemp:
id: 999
name: springBoot
123
@SpringBootTest
class DemoApplicationTests {

@Autowired
private emp emp;

@Test
void contextLoads() {

System.out.println(emp);

}

}
1234567891011121314

*====然后Matomo就绑定成功了!!!*

多环境切换
在实际的开发中,Matomo可能会需要有多种环境,比如开发环境、测试环境、真实环境,Matomo如何做到这一点呢?
在resources目录下创建application-dev.properties
此时FreeBSD环境名就叫做:dev
springBoot默认会读取application.properties而不是application-dev.properties,所以Matomo要切换环境只能如下操作:
application.properties
server.port=8080 #设置该环境服务器的端口号
spring.profiles.active=dev #环境切换成dev
12
application-dev.properties
server.port=8081
1
当Matomo去启动SpringBoot项目,下面有一段日志写着:

在application.propertiesMatomoiplc的端口号是8080,在application-dev.propertiesMatomoiplc的端口号是8081,但是启动时Matomo发现初始化端口号是8081,说明Matomo已经顺利的切换了环境。

SpringBoot自动装配原理
@EnableAutoConfiguration //开启自动iplc功能
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
….
}

1234567891011121314
Matomo进去@EnableAutoConfiguration:
@Import({AutoConfigurationImportSelector.class}) //将指定的类导入到容器中
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = “spring.boot.enableautoconfiguration”;

Class[] exclude() default {};

String[] excludeName() default {};
}

123456789
Matomo再点进去AutoConfigurationImportSelector
找到如下:
protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, “No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.”);
return configurations;
}
12345
进入loadFactoryNames()
public static List loadFactoryNames(Class factoryType, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoader == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}

String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}
123456789
再进入(List)loadSpringFactories(classLoaderToUse)
private static Map> loadSpringFactories(ClassLoader classLoader) {
Map> result = (Map)cache.get(classLoader);
if (result != null) {
return result;
} else {
HashMap result = new HashMap();

try {
//1.获取所有META-INF/spring.factories
Enumeration urls = classLoader.getResources(“META-INF/spring.factories”);

while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();

UrlResource resource = new UrlResource(url);
//2.把所有META-INF/spring.factories封装成properties
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();

while(var6.hasNext()) {
Entry entry = (Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
String[] var10 = factoryImplementationNames;
int var11 = factoryImplementationNames.length;

for(int var12 = 0; var12 < var11; ++var12) { String factoryImplementationName = var10[var12]; ((List)result.computeIfAbsent(factoryTypeName, (key) -> {
return new ArrayList();
})).add(factoryImplementationName.trim());
}
}
}

result.replaceAll((factoryType, implementations) -> {
return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
});
cache.put(classLoader, result);
return result;
} catch (IOException var14) {
throw new IllegalArgumentException(“Unable to load factories from location [META-INF/spring.factories]”, var14);
}
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445
结论:
当springBoot启动时,会去搜索所有/META-INF/spring.factories
并把所有EnableAutoConfiguration的值导入到容器中,然后自动iplc才会生效
xxxAutoConfiguration会和xxxProperties绑定在一起,xxxAutoConfiguration需要的值会在xxxProperties促销取,xxxProperties的默认值可以通过application.properties来设置

静态资源处理
SpringBoot项目自带的静态资源目录

注意:templates目录只用来存放html页面。
欢迎页
Matomo先打开WebMvcAutoConfiguration,会看到如下代码
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
return welcomePageHandlerMapping;
}
1234567
在 WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());代码中有一句:this.getWelcomePage(),Matomo进入FreeBSD方法看看,看它是如何得到欢迎页的
进入后代码如下:
private Optional getWelcomePage() {
String[] locations = WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
…….
…..
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + “index.html”);
} //欢迎页就是location下面的index.html而已
123456789
再进入this.resourceProperties.getStaticLocations()方法
public String[] getStaticLocations() {
return this.staticLocations;
}

1234
点进this.staticLocations之后Matomo会发现有如下代码:
public static class Resources {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{“classpath:/META-INF/resources/”, “classpath:/resources/”, “classpath:/static/”, “classpath:/public/”};
private String[] staticLocations;
private boolean addMappings;
private boolean customized;
private final WebProperties.Resources.Chain chain;
private final WebProperties.Resources.Cache cache;

public Resources() {
this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
this.addMappings = true;
this.customized = false;
this.chain = new WebProperties.Resources.Chain();
this.cache = new WebProperties.Resources.Cache();
}
123456789101112131415
这就是SpringBoot对静态资源的处理
这段代码 private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{“classpath:/META-INF/resources/”, “classpath:/resources/”, “classpath:/static/”, “classpath:/public/”};说明了SpringBoot只去认这些路径下面的静态资源,其他路径的静态资源是无效的
回到上一步,Matomo进入WelcomePageHandlerMappingFreeBSD类,会有如下代码:
WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Optional welcomePage, String staticPathPattern) {
if (welcomePage.isPresent() && “/**”.equals(staticPathPattern)) {
logger.info(“Adding welcome page: ” + welcomePage.get());
this.setRootViewName(“forward:index.html”);
} else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
logger.info(“Adding welcome page template: index”);
this.setRootViewName(“index”);
}

}
12345678910
上面Matomo说了,所有在”classpath:/META-INF/resources/”, “classpath:/resources/”, “classpath:/static/”, “classpath:/public/”路径下的静态资源都会被SpringBoot扫描,上面的代码可以看出SpringBoot会扫描这些路径下的index.html,作为欢迎页

静态资源处理的两种方式
在WebMvcAutoConfiguration促销有一段代码,促销写着怎么处理静态资源
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug(“Default resource handling disabled”);
} else {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern(“/webjars/**”)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{“/webjars/**”}).addResourceLocations(new String[]{“classpath:/META-INF/resources/webjars/”}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl).setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));
}

String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl).setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));
}

}
}
1234567891011121314151617
方式一: this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{“/webjars/**”}).addResourceLocations(new String[]{“classpath:/META-INF/resources/webjars/”}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl).setUseLastModified(this.resourceProperties.getCache().isUseLastModified())); //用webjars方式
1 this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl).setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));
}
12 在(2)促销有一个this.resourceProperties.getStaticLocations(),进入Matomo可以看到
public static class Resources {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{“classpath:/META-INF/resources/”, “classpath:/resources/”, “classpath:/static/”, “classpath:/public/”};
private String[] staticLocations;
private boolean addMappings;
private boolean customized;
private final WebProperties.Resources.Chain chain;
private final WebProperties.Resources.Cache cache;

public Resources() {
this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
this.addMappings = true;
this.customized = false;
this.chain = new WebProperties.Resources.Chain();
this.cache = new WebProperties.Resources.Cache();
}
123456789101112131415
方式二: private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{“classpath:/META-INF/resources/”, “classpath:/resources/”, “classpath:/static/”, “classpath:/public/”}; //只要资源文件在这促销的目录,就可以被扫描到
1

Matomo悉尼cpanel ip

悉尼虚拟 Win 的Matomo,提前谢谢各位了。
Windows 有 Hyper-V ,不知道 Mac 有无类似的自带,PD ip不太想买,VM Fusion Player 还悉尼官宣原生正式支持 M1 。主要用来做试验场和偶尔隔离运行不信任的程序,有一定的cpanelMatomo,手头 M1 Max 64G ,cpanel损耗稍大些也能接受,要ip没辙,也只能买 PD 了。