关于spring:三Java版Spring-Cloud-B2B2C-o2o鸿鹄云商平台技术框架

公司要搭建将来服务开发的统一标准,也思考到框架的可拓展及可伸缩性,可能顺应时代的潮流,鸿鹄云商平台(honghu)业务的可拓展性比拟随性,思考到将来经营计划多样化及疾速响应产品&用户需要、新业务的疾速迭代变更,作为平台的总架构师,我举荐公司应用以后业界最风行的Spring Cloud散布式微服务云解决方案来施行产品b2b2c云商平台研发,技术架构如下:(企业架构源码能够加求球:三五三六二四七二五九) MICROSERVICES: 前端框架: Vue.js、BootStrap、H5、CSS3、小程序 缓存治理: Redis、MongoDB 数据管理: RDBMS、NoSQL、Object Store 数据拜访/DAO:DTO、Spring Data、OSS API、Mybatis RUNTIME: Spring Boot 业务服务: 商品、领取、会员、模板、音讯、结算、库存、订单、集体核心… 微服务框架/Spring Cloud: Eureka、Config、API Geteway、Bus、Stream、RabbitMQ&KafKa、Turbine、Zipkin... INFRASTRUCTURE: 日志治理/剖析: Logback、Sleuth (SpringCloud)、Zipkin、ELK 负载平衡: Ribbon (Netflix, 客户端) 熔断器/服务监控: Hystrix (Netflix)、Turbine、Hystrix Dashboard (Netflix) 平台: Docker DEVOPS: 源代码治理: svn || GitHub 我的项目构建: maven 继续集成 CI: Jenkin 继续测试 CT: Junit Cucumber 以上是我参加的Spring Cloud B2B2C O2O鸿鹄云商平台-技术框架解决方案,从当初开始,我会将每一个细节点落实到文章上,心愿可能帮忙更多的敌人。

November 20, 2020 · 1 min · jiezi

关于spring:6-自定义容器类型元素验证类级别验证多字段联合验证

明天搬砖不狠,今天位置不稳。本文已被 https://www.yourbatman.cn 收录,外面一并有Spring技术栈、MyBatis、JVM、中间件等小而美的专栏供以收费学习。关注公众号【BAT的乌托邦】一一击破,深刻把握,回绝浅尝辄止。 ✍前言你好,我是YourBatman。 本文是上篇文章的续篇,集体倡议可先花3分钟移步上篇文章浏览一下:5. Bean Validation申明式验证四大级别:字段、属性、容器元素、类 很多人说Bean Validation只能验证单属性(单字段),但我却说它能实现99.99%的Bean验证,不信你可持续浏览本文,是否解你纳闷。 版本约定Bean Validation版本:2.0.2Hibernate Validator版本:6.1.5.Final✍注释本文接上文叙述,持续介绍Bean Validation申明式验证四大级别中的:容器元素验证(自定义容器类型)以及类级别验证(也叫多字段联结验证)。 据我理解,很多小伙伴对这部分内容并不相熟,遇到相似场景往往被迫只能是一半BV验证 + 一半事务脚本验证的形式,显得洋不洋俗不俗。 本文将给出具体案例场景,而后对立应用BV来解决数据验证问题,心愿能够帮忙到你,给予参考之作用。 自定义容器类型元素验证通过上文咱们曾经晓得了Bean Validation是能够对形如List、Set、Map这样的容器类型外面的元素进行验证的,内置反对的容器尽管能cover大部分的应用场景,但未免有的场景仍旧不能笼罩,而且这个可能还十分罕用。 譬如咱们都不生疏的办法返回值容器Result<T>,构造形如这样(最简模式,仅供参考): @Datapublic final class Result<T> implements Serializable { private boolean success = true; private T data = null; private String errCode; private String errMsg;}Controller层用它包装(装载)数据data,形如这样: @GetMapping("/room")Result<Room> room() { ... }public class Room { @NotNull public String name; @AssertTrue public boolean finished;}这个时候心愿对Result<Room>外面的Room进行合法性验证:借助BV进行申明式验证而非硬编码。心愿这么写就能够了:Result<@Notnull @Valid LoggedAccountResp>。显然,缺省状况下即便这样申明了束缚注解也是有效的,毕竟Bean Validation基本就“不意识”Result这个“容器”,更别提验证其元素了。 好在Bean Validation对此提供了扩大点。上面我将一步一步的来对此提供实现,让验证优雅再次起来。 自定义一个能够从Result<T>里提取出T值的ValueExtractor值提取器Bean Validation容许咱们对自定义容器元素类型进行反对。通过后面这篇文章:4. Validator校验器的五大外围组件,一个都不能少 晓得要想反对自定义的容器类型,须要注册一个自定义的ValueExtractor用于值的提取。 ...

November 20, 2020 · 2 min · jiezi

关于spring:xml方式自定义实现Ioc容器

@[TOC] xml形式自定义实现Ioc容器应用xml实现自定义简略的Ioc容器 前言平时开发过程中,咱们都是应用Spring来进行开发,Spring外围的Ioc容器帮忙咱们去创建对象这一过程被称作管制反转也叫Ioc在实例化一个对象时候,这个对象中用到一个对象类型的属性,容器把这个对象注入到实例化对象的过程被称作依赖注入简称DI Ioc和DI说的是一个事件,针对的侧重点不同,IOC是站在容器角度创建对象,DI是站在应用的角度,注入应用对象; 没有IOC容器的时候 模仿银行转账例子转账接口 public interface AccountDao { Account queryAccountByCardNo(String cardNo) throws Exception; int updateAccountByCardNo(Account account) throws Exception;}接口实现类 public class JdbcAccountDaoImpl implements AccountDao { public void init() { System.out.println("初始化办法....."); } public void destory() { System.out.println("销毁办法......"); } @Override public Account queryAccountByCardNo(String cardNo) throws Exception { //从连接池获取连贯 Connection con = DruidUtils.getInstance().getConnection(); String sql = "select * from account where cardNo=?"; PreparedStatement preparedStatement = con.prepareStatement(sql); preparedStatement.setString(1,cardNo); ResultSet resultSet = preparedStatement.executeQuery(); Account account = new Account(); while(resultSet.next()) { account.setCardNo(resultSet.getString("cardNo")); account.setName(resultSet.getString("name")); account.setMoney(resultSet.getInt("money")); } resultSet.close(); preparedStatement.close(); //con.close(); return account; } @Override public int updateAccountByCardNo(Account account) throws Exception { // 从连接池获取连贯 // 革新为:从以后线程当中获取绑定的connection连贯 Connection con = DruidUtils.getInstance().getConnection(); String sql = "update account set money=? where cardNo=?"; PreparedStatement preparedStatement = con.prepareStatement(sql); preparedStatement.setInt(1,account.getMoney()); preparedStatement.setString(2,account.getCardNo()); int i = preparedStatement.executeUpdate(); preparedStatement.close(); //con.close(); return i; }}业务接口 ...

November 20, 2020 · 4 min · jiezi

关于spring:手把手教你5分钟从零开发一款简易的IDEA插件项目经验毕设不愁了

我这个人没事就喜爱举荐一些好用的 IDEA 插件给大家。这些插件极大水平上进步了咱们的生产效率以及编码舒适度。 不晓得大家有没有想过本人开发一款 IDEA 插件呢? 我本人想过,然而没去尝试过。刚好有一位读者想让我写一篇入门 IDEA 开发的文章,所以,我在周末就花了一会工夫简略理解一下。 不过,这篇文章只是简略带各位小伙伴入门一下 IDEA 插件开发,集体精力有限,临时不会深入探讨太多。如果你曾经有 IDEA 插件开发的相干教训的话,这篇文章就能够不必看了,因为会节约你 3 分钟的工夫。 好的废话不多说!咱们间接开始! 01 新建一个基于 Gradle 的插件我的项目这里咱们基于 Gradle 进行插件开发,这也是 IntelliJ 官网的举荐的插件开发解决方案。 第一步,抉择 Gradle 我的项目类型并勾选上相应的依赖。 第二步,填写我的项目相干的属性比方 GroupId、ArtifactId。 第三步,静静期待我的项目下载相干依赖。 第一次创立 IDEA 插件我的项目的话,这一步会比较慢。因为要下载 IDEA 插件开发所需的 SDK 。 02 插件我的项目构造概览新建实现的我的项目构造如下图所示。 这里须要额定留神的是上面这两个配置文件。 plugin.xml :插件的外围配置文件。通过它能够配置插件名称、插件介绍、插件作者信息、Action 等信息。 <idea-plugin> <id>github.javaguide.my-first-idea-plugin</id> <!--插件的名称--> <name>Beauty</name> <!--插件的作者相干信息--> <vendor email="koushuangbwcx@163.com" url="https://github.com/Snailclimb">JavaGuide</vendor> <!--插件的介绍--> <description><![CDATA[ Guide哥代码开发的第一款IDEA插件<br> <em>这尼玛是什么垃圾插件!!!</em> ]]></description> <!-- please see https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html on how to target different products --> <depends>com.intellij.modules.platform</depends> <extensions defaultExtensionNs="com.intellij"> <!-- Add your extensions here --> </extensions> <actions> <!-- Add your actions here --> </actions></idea-plugin>build.gradle :我的项目依赖配置文件。通过它能够配置我的项目第三方依赖、插件版本、插件版本更新记录等信息。 ...

November 19, 2020 · 2 min · jiezi

关于spring:一Java版Spring-Cloud-B2B2C-o2o鸿鹄云商平台概述

近期公司正在降级Spring Cloud版本的b2b2c o2o鸿鹄云商平台,我亲自参加了整个产品的研发及降级工作。大略统计了一下,用Java Spring Cloud技术研发电子商务平台的公司少之甚少,借此我想将整个研发的过程通过博客的形式分享进去,心愿各位IT网友看到此系列文章多给自己留言,一起提高。 第一篇文章我不会过多的强调技术,而是通过清单形式给大家展现一下整个b2b2c o2o全套解决方案 Java版Spring Cloud B2B2C鸿鹄云商平台全套解决方案 应用技术: Spring Cloud+Spring Boot+Mybatis+微服务+服务监控+可视化经营 B2B2C平台: 平台治理端(蕴含自营)商家平台端(多商户入驻)PC买家端、手机wap/公众号买家端微服务(30个通用微服务如:商品、订单、购物车、集体核心、领取、文件、经营等,反对原生Android、ios、react、小程序、vue、h5等前端调用)聚合小程序SAAS小程序: 平台治理端商家平台端(多商户入驻)小程序数据收集和入驻微服务(30个通用微服务如:商品、订单、购物车、集体核心、领取、文件、经营等,反对原生Android、ios、react、小程序、vue、h5等前端调用)SAAS小程序B2C电子商城: 平台治理端(蕴含自营)PC买家端、手机wap/公众号买家端微服务(30个通用微服务如:商品、订单、购物车、集体核心、领取、文件、经营等,反对原生Android、ios、react、小程序、vue、h5等前端调用)小程序(聚合)B2B供应链平台: 供应链平台治理端供应链商家治理端(多商户入驻)PC商家洽购、公布洽购需要微服务(30个通用微服务如:商品、订单、购物车、集体核心、领取、文件、经营等,反对原生Android、ios、react、小程序、vue、h5等前端调用)O2O新批发平台: 平台治理端商家平台端(多商户入驻、门店账号、商品公布治理)PC买家端、手机wap/公众号买家端门店后盾(治理商品、订单、库存)+ 收银台微服务(30个通用微服务如:商品、订单、购物车、集体核心、领取、文件、经营等,反对原生Android、ios、react、小程序、vue、h5等前端调用)小程序以上是我参加的Spring Cloud B2B2C o2o鸿鹄云商平台,从当初开始,我会将每一个细节点落实到文章上,心愿可能帮忙更多的敌人。(企业架构源码能够加求球:三五三六二四七二五九)

November 19, 2020 · 1 min · jiezi

关于spring:Jackson使用指北

Jackson应用指北1. 概述Jackson是目前在web开发中应用最多,速度最快的一种json序列化和反序列化框架。本文次要联合Jackson在我的项目中的理论应用进行介绍。 2. 字段疏忽2.1 json转POJO时,疏忽某些字段只须要在实体类上加上@JsonIgnoreProperties(ignoreUnknown = true)注解就能够。 2.2 POJO转json时,疏忽某些字段@JsonIgnore注解用来疏忽某些字段,能够用在Field或者Getter办法上,用在Setter办法时,和Filed成果一样 3. json转换为POJO3.1 json字符串间接转POJOobjectMapper.readValue(json, xxx.class) 实用于json字符串与POJO间接一一对应。 3.2 json字符串转JsonNode JsonNode rootNode = objectMapper.readTree(json); // 获取其中某个字段的数据 JsonNode dataNode = rootNode.findValue("xxx"); // 将数据反序列化为POJO objectMapper.treeToValue(dataNode, xxx.class);实用于Json字符串的某一部分与JsonNode对应。先获取json响应中的某一部分数据,再将该数据转换为POJO 3.3 json转泛型类AiReply<SensitiveImageReply> reply = objectMapper.readValue(json, new TypeReference<AiReply<SensitiveImageReply>>() {});3.4 json转数组和列表 List<Person> personList = new ArrayList<Person>() { { add(new Person("yangjian", 22)); add(new Person("zhanghaoman", 22)); } }; String personJson = this.objectMapper.writeValueAsString(personList); List<Person> persons = this.objectMapper.readValue(personJson, List.class); System.out.println("persons = " + persons);3.5 类拷贝 // 拷贝成map Person person = new Person("yangjian", 23); String json = this.objectMapper.writeValueAsString(person); Map<String, Object> map = this.objectMapper.convertValue(person, Map.class); // 链表到数组拷贝 List<String> list = new ArrayList<String>() { { add("one"); add("two"); } }; String[] strings = this.objectMapper.convertValue(list, String[].class); System.out.println("this.objectMapper.writeValueAsString(strings) = " + this.objectMapper.writeValueAsString(strings));4. POJO转换为json4.1 设置视图@JsonView(xxx.class)注解能够实现视图显示,序列化的json只会蕴含有雷同视图润饰的字段。并且,视图能够继承。此注解,POJO类上和controller的办法上都须要加。 ...

November 19, 2020 · 2 min · jiezi

关于spring:Java初始化静态变量的时间顺序

1. 开始吧!明天,咱们来探讨交换下动态变量初始化过程。Java虚拟机在类加载期间也同样遵循这个过程。 2. 初始化过程在较高的档次上,JVM执行以下步骤: 首先,加载并链接类。而后,这个过程的“初始化”阶段解决动态变量初始化。最初,调用与类关联的main办法。在接下来的探讨中,咱们来摸索下类变量初始化。 3. 类变量在Java中,动态变量也称为类变量。也就是说,它们属于一个类,而不是一个特定的实例。因而,类初始化的时候也将初始化动态变量相同,类的实例 初始化的时候也将初始化 实例变量(非动态变量)。类的所有实例共享该类的动态变量。以 StaticVariableDemo 类为例: public class StaticVariableDemo { public static int i; public static int j = 20; public StaticVariableDemo() {}}First, the JVM creates a Class object for the class StaticVariableDemo. Next, the static field initializers assign a meaningful default value to the static fields. In our example above, the class variable i is first initialized with an int default value of zero. ...

November 19, 2020 · 1 min · jiezi

关于spring:NoSuchBeanDefinitionExceptionNo-bean-named-shiroFilter

在spring集成shiro的我的项目时,启动我的项目产生了异样: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'shiroFilter' available at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687) at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1205) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1091) at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:337) at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:242) at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:241) at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:281) at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:262) at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:106) at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4548) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5193) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705) at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1720) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:287) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:479) at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:428) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:287) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) at com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:468) at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468) at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309) at java.security.AccessController.doPrivileged(Native Method) at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1408) at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)18-Nov-2020 18:49:52.369 淇℃伅 [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext解决方案1、首先查看一下web.xml与shiro配置文件中bean的id是否统一 (xml中没问题) ...

November 18, 2020 · 1 min · jiezi

关于spring:Java泛型中-和-extends-Object的异同分析

置信很多人和我一样,接触Java多年,却仍旧搞不清楚 Java 泛型中 <?>和 <? extends Object>的类似和不同。然而,这应该是一个比拟高端大气上档次的Question, 在咱们进行深刻的探讨之前,有必要对Java泛型有一个根底的理解。具体请看上一篇文章!重温Java泛型,带你更深刻地了解它,更好的应用它! 1. 泛型产生的背景在 JDK5 中引入了泛型来打消编译时谬误和增强类型安全性。这种额定的类型安全性打消了某些用例中的强制转换,并使程序员可能编写泛型算法,这两种办法都能够生成更具可读性的代码。 例如,在 JDK5 之前,咱们必须应用强制转换来解决列表的元素。这反过来又产生了一类特定的运行时谬误: List aList = new ArrayList();aList.add(new Integer(1));aList.add("a_string"); for (int i = 0; i < aList.size(); i++) { Integer x = (Integer) aList.get(i);}当初,咱们想解决两个问题: 咱们须要一个显式转换来从 aList 中提取值——类型取决于左侧的变量类型(在本例中为Integer)当咱们试图将 a_string 转换为 Integer 时,在第二次迭代中会呈现运行时谬误。泛型填补了这个空白,代码如下: List<Integer> iList = new ArrayList<>();iList.add(1);iList.add("a_string"); // compile time error for (int i = 0; i < iList.size(); i++) { int x = iList.get(i);}执行上述代码,编译器会通知咱们,无奈将 a_string 增加到 Integer 类型的 List 中,这比起在运行时才发现异常要好很多。而且,不须要显式转换,因为编译器曾经晓得 iList 蕴含 Integer类型的数据。另外,因为主动拆箱的关系,咱们甚至不须要应用 Integer 类型,它的原始类型就足够了。 ...

November 18, 2020 · 2 min · jiezi

关于spring:spring-boot-打印请求到log

将申请打印到log 的办法很多,参考了上面三个文章,用了最简略的一个办法,应用spring中内置的CommonsRequestLoggingFilter 用来打印log 新建bean@Beanpublic CommonsRequestLoggingFilter logFilter() { CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter(); filter.setIncludeQueryString(true); filter.setIncludePayload(true); filter.setMaxPayloadLength(10000); filter.setIncludeHeaders(false); filter.setAfterMessagePrefix("REQUEST DATA : "); return filter;}批改application.propertieslogging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=debug参考Spring Boot - How to log all requests and responses with exceptions in single place?Spring – Log Incoming RequestsLogging Requests and Responses in Spring (including body)

November 17, 2020 · 1 min · jiezi

关于spring:Spring-依赖注入最佳实践

【注】本文译自:https://springframework.guru/... 在本文中,我将向你展现如何在 Spring Framework 的依赖项注入中应用 Project Lombok 以获得最佳实际。 Spring 框架自身具备多种执行依赖项注入的形式。选项的灵活性是 Spring 框架的劣势。然而,并非所有的依赖项注入选项都被视为最佳实际。有些实际上不太好。 依赖注入示例 我提供了一些设置示例,供咱们查看必须应用的各种依赖项注入选项。 让咱们以 Spring Service 为例。就咱们的目标而言,该服务具备一种返回字符串的办法。咱们将应用“service”,并应用 Spring将其注入一些模仿控制器中。请记住,咱们只是在摸索如何应用 Spring Framework 进行依赖项注入。 示例 Servicepublic class MyService { public String getHello(){ return "Hello"; }} 咱们的 Field 领有一项私有属性的服务。咱们能够注解该字段,Spring 将注入该服务的实例。 属性注入Field Controller@Controllerpublic class FieldController { @Autowired MyService myService; public String saySomething(){ return myService.getHello(); }} 这只是一个私有属性,没有 setter。显然,这不是一个好的实际,不举荐这样做。 咱们能够对此进行一些改良,将该字段的拜访权限设为公有。Spring Framework 的确容许你主动拆卸公有字段。你的确看到有人这样做。Spring 将执行一些反射魔术来执行依赖项注入 公有 Field Controllerpublic class PrivateFieldController { @Autowired private MyService myService; public String saySomething(){ return myService.getHello(); }} 只管只应用公有字段比拟好,然而测试却成了一个令人头痛。你要么须要启动 Spring Context,要么应用一些 Spring 实用程序来执行依赖注入以进行测试。不是世界末日,但总的来说很烦人。 咱们能够通过为公有属性提供 setter 来改善这一点。Getter 和 Setter 通常被认为是面向对象编程中的最佳实际。通过注解 setter 办法,批示 Spring 应用 setter 进行依赖项注入很简略。 ...

November 17, 2020 · 2 min · jiezi

关于spring:微服务框架基于开源技术的分布式服务化框架

采纳微服务架构,升高了零碎之间的耦合性,升高了单个利用故障对业务零碎的影响,同时采纳该架构,为未来的继续集成(Devops)打下技术根底。同时也升高了团队之间的相互依赖,进步了工作效率   基于spring boot, spring cloud和netflix等开源技术搭建微服务架构Netflix Eureka作为服务注册和发现的实现计划。(Eureka是一套弹性服务注册实现计划)基于客户端的负载平衡,Ribbon实现额定负载平衡算法,包含可用性过滤、加权响应工夫以及可用域亲和等Oauth Client&Server 是基于spring security oauth,实现微服务的平安认证JWT&Token&Redis实现微服务对立SSO单点登录认证计划(可选)(企业架构源码能够加求球:三五三六二四七二五九)

November 17, 2020 · 1 min · jiezi

关于spring:Spring-Boot-创建-Docker-镜像

随着越来越多的组织转向容器和虚构服务器,Docker正成为软件开发工作流程中一个更重要的局部。为此,Spring Boot 2.3中最新的性能之中,提供了为Spring Boot应用程序创立 Docker 镜像的能力。 这篇文章的目标,就是为了给大家介绍如何为 Spring Boot 应用程序创立 Docker 镜像。 1. 传统Docker构建应用Spring Boot 构建 Docker 镜像的传统办法是应用 Dockerfile 。上面是一个简略的例子: FROM openjdk:8-jdk-alpineEXPOSE 8080ARG JAR_FILE=target/demo-app-1.0.0.jarADD ${JAR_FILE} app.jarENTRYPOINT ["java","-jar","/app.jar"]而后咱们能够应用 docker build 命令来创立 Docker 映像。这对大多数应用程序都很好,但也有一些毛病。 首先,咱们应用的是 Spring Boot 创立的 fat jar。这会影响启动工夫,尤其是在集装箱环境中。咱们能够通过增加jar文件的合成内容来节俭启动工夫。 其次,Docker镜像是分层构建的。Spring Boot fat jar 的个性使得所有的利用程序代码和第三方库都放在一个层中。这意味着即便只有一行代码更改,也必须从新构建整个层。 通过在构建之前合成 jar ,利用程序代码和第三方库各自取得本人的层。这样,咱们便能够利用Docker的缓存机制。当初,当某一行代码被更改时,只须要从新构建相应的层。 思考到这一点,让咱们看看Spring Boot 如何改良创立Docker镜像的过程。 2. BuildpacksBuildPacks 是一种提供框架和应用程序依赖性的工具。 例如,给定一个Spring Boot fat jar,一个buildpack将为咱们提供Java运行时。这使咱们能够跳过 Dockerfile 并主动取得一个正当的docker 镜像。 Spring Boot 包含对 bulidpacks 的Maven和Gradle反对。例如,应用Maven构建时,咱们将运行以下命令: ./mvnw spring-boot:build-image咱们察看下一些相干的输入,看看产生了什么: ...

November 17, 2020 · 2 min · jiezi

关于spring:Spring改变版本号命名规则此举对非英语国家很友好

要想改变命运,首先扭转本人。本文已被 https://www.yourbatman.cn 收录,外面一并有Spring技术栈、MyBatis、JVM、中间件等小而美的专栏供以收费学习。关注公众号【BAT的乌托邦】一一击破,深刻把握,回绝浅尝辄止。 ✍前言你好,我是YourBatman。 还记得在往年5月份样子看到了一篇来自Pivotal的邮件,大抵内容是说Spring扭转了版本号的命名规定,过后本着先珍藏一下筹备早晨再看,而后,就没有而后了。 直到前些天忽然看到了篇题目为:Spring Data 2020.0.0正式公布的文章,这才让我把此事联想了起来,因而才决定写此文记录一下,顺带分享给你。 若你已苦于Spring Cloud的版本号命名形式,那么本文给你带来了曙光 ✍注释天下苦Spring Cloud版本命名久矣。在正式开始之前,管生管养的A哥无意对这其中的相干名词进行解释,不便了解本文。 Release TrainRelease Train直译过去意思为:发版火车/火车发版。火车大家不生疏,它有一个显著的特点:定时定点发车。这里的发车在软件畛域就等同于软件的发版。 为何须要Release Train发版模式?在公司还很小很小的时候,整个公司可能只有一个软件,版本公布十分的简略,没什么须要协调的,发就完了。然而,一旦公司疾速倒退变得比拟大后,外围产品性能数以十、百计,各功能模块由不同的团队负责,沟通老本显著升高,单单在版本上稍不留神就会产生各种问题,很容易给人一种“乱如麻”的感觉。 应用Release Train的发版模式就能很大水平上防止这些问题,能够这样做:规定每个月的最初一天(准确的发版日期)须要发一版(类比于火车发车),那么就能够以这个工夫点为deadline,参加的的各方包含产品经理、RD、QA等等都提前沟通好需要内容,并做好打算,充沛做好对立发车的筹备。在这期间,如果两头某一团队呈现问题跟不上节奏了,那么请及时下车(前提是管制好下车的影响面),不要影响整体发车工夫点。 总的来讲:火车是按点准时登程的,各方应按点上车,假使本次赶不上车的那么就请等下一趟车。通过这种形式能够确保软件产品的继续迭代,保障产品的稳定性,这就是Release Train发版模式。 在理论的软件产品中,能够认为略微大一点的软件都是依照此模式来继续迭代的,比方IOS、maxOS、MIUI、Spring Cloud等等。这些软件版本在命名形式上不同但均遵循肯定法则: IOS 14、IOS 14.1、IOS14.1.1macOS Mojave、macOS SierraSpring Cloud Greenwich、Spring Cloud HoxtonProject Module如果说依照Release Train发版模式收回的一个版本代表着一个大的产品版本号,那么Project Module就代表其外部的模块。个别一个软件产品由N多个模块组成,以最新的Spring Data 2020.0.0版本为例,内含有多个Project Module模块: Spring Data Commons 2.4Spring Data JDBC 2.1Spring Data JPA 2.4Spring Data MongoDB 3.1Spring Data KeyValue 2.4Spring Data LDAP 2.4Spring Data Elasticsearch 4.1...Semantic Versioning语义化版本号,有被称作语义化版本控制标准,简称“SemVer”。它是一套版本号规定的规范/标准,用于改善软件版本号格局凌乱问题,顺便对立一下版本号所表白的含意。官方主页是:https://semver.org 版本号组成SemVer版本号次要由三个局部组成,每个局部是一个非负整数,局部和局部之间用.分隔:主版本号.次版本号.订正号(简写为x.y.z)。上面对这三局部做出解释(约定): 主版本号:只有进行非向下兼容的批改或者颠覆性的更新时,主版本号加1 话外音:扭转很大,暴力式更改次版本号:进行向下兼容的批改或者增加兼容性的新性能时,次版本号加1 话外音:扭转不很大,个别是向下兼容的。值得注意的是:这里指的是个别,有些状况也存在不兼容状况也是容许的,当然不能是次要性能不兼容补丁号:没有新性能退出,个别修复bug、优化代码等,补丁号加1 话外音:此版本号可释怀无缝降级对于这三局部还有两点值得注意: ...

November 16, 2020 · 1 min · jiezi

关于spring:Spring框架中的Bean对象的理解

Bean对象的定义?在Spring框架中由Spring创立和治理的对象的对象称之为Bean对象。 Bean对象的个性?Spring框架为了更加迷信的治理和利用Bean对象,为其设计相干个性,例如:懒加载、作用域以及生命周期办法。 懒加载(Lazy)在Spring框架中,默认会在启动时会创立所有的Bean对象,但有些bean对象如果长时间不必,启动时就创建对象,会占用其内存资源,从而造成肯定的资源节约,此时咱们能够基于懒加载策略提早对象的创立,在设计类时,在类上增加@Lazy注解,例如: package com.cy.pj.common.pool;@Component@Lazypublic class ObjectPool { public ObjectPool() { System.out.println("ObjectPool()"); }}其中,@Lazy注解中有一个value属性,其默认值为true示意提早加载。作用域(Scope)Spring框架创建对象当前,能够给对象一个作用域,目标是让对象在肯定范畴内能够进行重用,罕用有单例(singleton)和多例(prototype)两种,其中: singleton:此作用域指的是,名字和类型雷同的Bean对象实例在整个Spring容器中只能一份。此实例何时创立与类的提早加载个性配置无关,此实例创立当前,生命周期会由spring框架治理。prototype:此作用域指的是,每次从Spring容器获取对象都会创立新实例,此实例会在须要时创立与lazy个性无关,这个实例创立当前,spring能够对其初始化,但不负责销毁。基于注解@Scope形式设定Bean作用域,代码演示: package com.cy.pj.common.pool;、@Lazy@Scope("singlton")@Componentpublic class ObjectPool { public ObjectPool() { System.out.println("ObjectPool()"); }}Spring中默认bean对象的作用域为singleton,如果心愿是prototype能够应用@Scope("prototype")生命周期办法程序中每个对象都有生命周期,但不是每个对象类型定义时,都要定义生命周期办法,当一个Bean对象创立当前如果还需执行额定初始化,销毁之前也须要额定的其它资源的开释,Spring框架能够为类定义其生命周期办法。如果是注解形式,咱们能够采纳如下两个注解进行实现。 @PostConstruct 注解用于形容bean对象生命周期办法中的初始化办法,此办法会在对象的构造方法之后执行(是对象创立当前的初始化)。@PreDestroy 注解用于形容Bean对象生命周期办法中的销毁办法,此办法会在对象销毁之前执行(当作用域为prototype时,此办法不会执行)。代码演示: package com.cy.pj.common.pool;、@Lazy@Scope("singlton")@Componentpublic class ObjectPool { public ObjectPool() { System.out.println("ObjectPool()"); } @PostConstruct public void init() { System.out.println("init()"); } @PreDestroy public void close() { System.out.println("close()"); }}个别池对象都会设置一些生命周期办法,例如连接池。总结(Summary)本大节次要对Spring框架中的Bean对象个性做了一个概要剖析,能够通过这个剖析理解Spring框架是如何迷信利用bean对象的。

November 16, 2020 · 1 min · jiezi

关于spring:Spring源码分析之循环依赖及解决方案

Spring源码剖析之循环依赖及解决方案注释: 首先,咱们须要明确什么是循环依赖?简略来说就是A对象创立过程中须要依赖B对象,而B对象创立过程中同样也须要A对象,所以A创立时须要先去把B创立进去,但B创立时又要先把A创立进去...死循环有木有... 那么在Spring中,有多少种循环依赖的状况呢?大部分人只晓得两个一般的Bean之间的循环依赖,而Spring中其实存在三种对象(一般Bean,工厂Bean,代理对象),他们之间都会存在循环依赖,这里我给列举进去,大抵别离以下几种: 一般Bean与一般Bean之间一般Bean与代理对象之间代理对象与代理对象之间一般Bean与工厂Bean之间工厂Bean与工厂Bean之间工厂Bean与代理对象之间那么,在Spring中是如何解决这个问题的呢? 1. 一般Bean与一般Bean首先,咱们先构想一下,如果让咱们本人来编码,咱们会如何解决这个问题? 栗子当初咱们有两个相互依赖的对象A和B public class NormalBeanA { private NormalBeanB normalBeanB; public void setNormalBeanB(NormalBeanB normalBeanB) { this.normalBeanB = normalBeanB; }}public class NormalBeanB { private NormalBeanA normalBeanA; public void setNormalBeanA(NormalBeanA normalBeanA) { this.normalBeanA = normalBeanA; }}而后咱们想要让他们彼此都含有对象 public class Main { public static void main(String[] args) { // 先创立A对象 NormalBeanA normalBeanA = new NormalBeanA(); // 创立B对象 NormalBeanB normalBeanB = new NormalBeanB(); // 将A对象的援用赋给B normalBeanB.setNormalBeanA(normalBeanA); // 再将B赋给A normalBeanA.setNormalBeanB(normalBeanB); }}发现了吗?咱们并没有先创立一个残缺的A对象,而是先创立了一个空壳对象(Spring中称为晚期对象),将这个晚期对象A先赋给了B,使得失去了一个残缺的B对象,再将这个残缺的B对象赋给A,从而解决了这个循环依赖问题,so easy! ...

November 16, 2020 · 4 min · jiezi

关于spring:SpringBoot系列3web启动流程简述

本文简要介绍下SpringBoot中,web我的项目启动时一些重要的流程: SpringBoot中用于web的IOC容器启动流程HTTP的url是如何和controller中的办法绑定的?罕用的web我的项目配置参数SpringBoot中用于web的IOC容器启动流程Spring的外围就是ApplicationContext,启动流程理论就是调用其子接口ConfigurableApplicationContext的refresh()办法。 在Spring中,有一个ConfigurableApplicationContext的实现类AbstractApplicationContext,该类中实现了refresh()的流程。SpringBoot默认提供的启动类都是它的子类。 默认状况下,web服务应用的就是AnnotationConfigServletWebServerApplicationContext,它的父类是ServletWebServerApplicationContext,也是AbstractApplicationContext的间接子类。类之间的继承关系如下: 因而,对于web启动流程能够剖析ServletWebServerApplicationContext的refresh(),一个简化的启动流程如下: AbstractApplicationContext中实现的refresh()流程中,蕴含了两个办法onRefresh()和finishRefresh()。 ServletWebServerApplicationContext就是通过重写这两个办法,实现了对web server的配置和启动。 来看下ServletWebServerApplicationContext的onRefresh()和finishRefresh() onRefresh()中次要是依据配置信息,初始化web Server,默认应用的就是Tomcat,依赖tomcat-embed-core设置之后,会持续IOC的启动流程,解决我的项目中的Bean在refresh()的最初,会调用finishRefresh(),并启动Tomcat,这之后才能够失常解决http申请。@Overrideprotected void onRefresh() { super.onRefresh(); try { createWebServer(); } catch (Throwable ex) { throw new ApplicationContextException("Unable to start web server", ex); }}@Overrideprotected void finishRefresh() { super.finishRefresh(); WebServer webServer = startWebServer(); if (webServer != null) { publishEvent(new ServletWebServerInitializedEvent(webServer, this)); }}HTTP的url是如何和controller中的办法绑定的?当提供restful api时,通常会在Controller类上应用@RestController注解,绑定的办法就是在该注解的解决逻辑中。 简略说下spring中注解的实现原理在Spring IOC注入流程中会在解决bean的不同阶段,顺次调用一些接口的全副实现类,例如InitializingBean,BeanPostProcessor等。 SpringBoot中的注解就是通过实现这些接口,在逻辑中判断bean是否持有指定注解,来对bean做非凡解决。 对@RestController等web注解的解决类次要是RequestMappingHandlerMapping,该类间接实现了InitializingBean接口,通过重写afterPropertiesSet办法实现解决逻辑。 url和办法绑定的具体流程上面次要看下RequestMappingHandlerMapping和其父类AbstractHandlerMethodMapping中对绑定逻辑的实现,次要函数调用流程如下: 能够看到,注册的大部分逻辑是在AbstractHandlerMethodMapping中,最终会把url和解决办法保留在一个Hashmap中。 上面对办法做简要阐明: RequestMappingHandlerMapping.afterPropertiesSet() 初始化配置,一些url解析器和解析规定。AbstractHandlerMethodMapping.initHandlerMethods()和processCandidateBean() 从IOC的beans中,筛选出蕴含@RestController等注解的controller bean。AbstractHandlerMethodMapping.detectHandlerMethods(Object handler) 检测controller bean,筛选出蕴含@PostMapping()或@GetMapping()等注解的办法。AbstractHandlerMethodMapping.MappingRegistry.register(T mapping, Object handler, Method method) ...

November 15, 2020 · 1 min · jiezi

关于spring:快速识别烂项目试试这款项目代码统计IDEA插件

编程是一个很微妙的事件,大部分的咱们把大部分工夫理论都花在了复制粘贴,而后批改代码下面。 很多时候,咱们并不关注代码品质,只有性能能实现,我才不论一个类的代码有多长、一个办法的代码有多长。 因而,咱们常常会碰到让本人想要骂街的我的项目,不过,说真的,你本人写的代码也有极大可能被后者 DISS。 为了疾速剖析我的项目状况,判断这个我的项目是不是一个“垃圾”我的项目,有一个办法挺简略的。 那就是对代码的总行数、单个文件的代码行数、正文行数等信息进行统计。 怎么统计呢? 首先想到的是 Excel 。不过,显然太麻烦了。 有没有专门用于代码统计的工具呢? 基于Perl语言开发的cloc(count lines of code)或者能够满足你的要求。 有没有什么更简略的方法呢? 如果你应用的是 IDEA 进行开发的话,举荐你能够应用一下 Statistic 这个插件。 咱们间接在 IDEA 的插件市场即可找到这个插件。我这里曾经装置好了。 如果你因为网络问题没方法应用 IDEA 自带的插件市场的话,也能够通过IDEA 插件市场的官网手动下载安装。 有了这个插件之后你能够十分直观地看到你的我的项目中所有类型的文件的信息比方数量、大小等等,能够帮忙你更好地理解你们的我的项目。 你还能够应用它看所有类的总行数、无效代码行数、正文行数、以及无效代码比重等等这些货色。 如果,你放心插件过多影响IDEA速度的话,能够只在有代码统计需要的时候开启这个插件,其余工夫禁用它就完事了! 闲聊最近有读者询问 IDEA插件开发相干的事件,我本人也挺感兴趣的,就简略学习了一下并总结了一篇入门 IDEA 插件开发的文章。预计会在下周收回。 微信搜“JavaGuide”回复“计算机根底”即可获取图解计算机根底+集体原创的 Java 面试手册。

November 14, 2020 · 1 min · jiezi

关于spring:十八-整合spring-cloud云架构-后台管理基础功能简介

1.  我的项目介绍 鸿鹄云开发平台是一个大型分布式、微服务、云架构、面向企业的   JavaEE体系疾速研发平台,基于模块化、服务化、原子化、热插拔的设计思维,应用成熟当先的无商业限度的支流开源技术构建。 采纳服务化的组件开发模式,可实现简单的业务性能。应用Maven进行我的项目的构建治理,采纳Jenkins进行继续集成,次要定位于大型分布式企业零碎或大型分布式互联网产品的架构。应用以后最风行最先进的Spring Cloud技术实现服务组件化及治理,真正为企业打造散布式微服务云架构平台。 2. 应用技术(技术应用太多,这里只列了一部分) SOA服务框架:SpringCloud 、SpringBoot、RestFul等 分布式缓存:Redis 模块化治理:Maven 数据库连接池:Alibaba Druid 外围框架:Spring framework、SpringBoot 长久层框架:MyBatis 平安框架:Apache Shiro 服务端验证:Hibernate Validator 任务调度:quartz 日志治理:SLF4J 1.7、Log4j 客户端验证:JQuery Validation 动静页签:easyuitab 前端框架:Bootstrap、Vue 3. 设计思维 分布式、微服务、云架构 JAVA语言开发、跨平台、高性能、高可用、平安、服务化、模块化、组件化、驱动式开发模式 4.  平台根底性能 用户治理:用户是零碎操作者,该性能次要实现零碎用户配置。 角色治理:角色菜单权限调配、设置角色按机构进行数据范畴权限划分。 权限治理:对系统中常常应用的一些较为固定的数据进行保护等。 菜单治理:配置零碎菜单,操作权限,按钮权限标识等。 部门治理:配置零碎组织机构,树结构展示,可随便调整上下级。 日志治理:零碎失常操作日志记录和查问;零碎异样信息日志记录和查问。 连接池监督:监督当期零碎数据库连接池状态,剖析零碎性能瓶颈。 5.  源码构造 6.    注册核心    7.    局部性能截图        欢送大家和我一起学习spring cloud构建微服务云架构,我这边会将近期研发的spring cloud微服务云架构的搭建过程和精华记录下来,帮忙更多有趣味研发spring cloud框架的敌人,大家来一起探讨spring cloud架构的搭建过程及如何使用于企业我的项目。企业架构源码能够加求球:三五三六二四七二五九

November 13, 2020 · 1 min · jiezi

关于spring:为什么大多数IOC容器使用ApplicationContext而不用BeanFactory

1. 引言Spring框架附带了两个IOC容器– BeanFactory 和 ApplicationContext. BeanFactory是IOC容器的最根本版本,ApplicationContext扩大了BeanFactory的性能。那么本篇文章中,咱们将通过理论例子理解这两个IOC容器之间的显著差别。 2. 提早加载 vs. 预加载BeanFactory 按需加载bean,而 ApplicationContext 则在启动时加载所有bean。因而,BeanFactory与ApplicationContext相比是轻量级的。让咱们用一个例子来了解它。 2.1. BeanFactory 提早加载假如咱们有一个名为 Student 单例Bean: public class Student { public static boolean isBeanInstantiated = false; public void postConstruct() { setBeanInstantiated(true); } //standard setters and getters}咱们将把 postConstruct() 办法定义为BeanFactory配置文件 ioc-container-difference-example.xml 中的 init method: <bean id="student" class="com.baeldung.ioccontainer.bean.Student" init-method="postConstruct"/>当初,让咱们编写一个测试用例来创立一个BeanFactory 来查看它是否加载了Student bean: @Testpublic void whenBFInitialized_thenStudentNotInitialized() { Resource res = new ClassPathResource("ioc-container-difference-example.xml"); BeanFactory factory = new XmlBeanFactory(res); assertFalse(Student.isBeanInstantiated());}这里,没有初始化 Student 对象。换句话说,只有 BeanFactory 被初始化了。只有当咱们显式调用getBean()办法时,BeanFactory 中定义的 bean 才会被加载。让咱们检查一下 Student bean 的初始化状况,咱们手动调用 getBean() 办法: ...

November 13, 2020 · 2 min · jiezi

关于spring:十七-整合spring-cloud云架构-消息驱动-Spring-Cloud-Stream

在应用spring cloud云架构的时候,咱们不得不应用Spring cloud Stream,因为消息中间件的应用在我的项目中无处不在,咱们公司前面做了娱乐方面的APP,在应用spring cloud做架构的时候,其中音讯的异步告诉,业务的异步解决都须要应用消息中间件机制。spring cloud的官网给出的集成倡议(应用rabbit mq和kafka),我看了一下源码和配置,只有把rabbit mq集成,kafka只是换了一个pom配置jar包而已,闲话少说,咱们就间接进入配置施行: 简介:Spring cloud Stream 数据流操作开发包,封装了与Redis,Rabbit、Kafka等发送接管音讯。 应用工具:rabbit,具体的下载和装置细节我这里不做太多解说,网上的实例太多了 创立commonservice-mq-producer音讯的发送者我的项目,在pom外面配置stream-rabbit的依赖1. <span style="font-size: 16px;"><!-- 引入MQ音讯驱动的微服务包,引入stream只须要进行配置化即可,是对rabbit、kafka很好的封装 --> 2. <dependency> 3. <groupId>org.springframework.cloud</groupId> 4. <artifactId>spring-cloud-starter-stream-rabbit</artifactId> 5. </dependency></span>在yml文件外面配置rabbit mq1. <span style="font-size: 16px;">server: 2. port: 5666 3. spring: 4. application: 5. name: commonservice-mq-producer 6. profiles: 7. active: dev 8. cloud: 9. config: 10. discovery: 11. enabled: true 12. service-id: commonservice-config-server 13. <span style="color: #ff0000;"># rabbitmq和kafka都有相干配置的默认值,如果批改,能够再次进行配置 14. stream: 15. bindings: 16. mqScoreOutput: 17. destination: honghu_exchange 18. contentType: application/json 20. rabbitmq: 21. host: localhost 22. port: 5672 23. username: honghu 24. password: honghu</span> 25. eureka: 26. client: 27. service-url: 28. defaultZone: http://honghu:123456@localhost:8761/eureka 29. instance: 30. prefer-ip-address: true</span>定义接口ProducerService1. <span style="font-size: 16px;">package com.honghu.cloud.producer; 3. import org.springframework.cloud.stream.annotation.Output; 4. import org.springframework.messaging.SubscribableChannel; 6. public interface ProducerService { 8. String SCORE_OUPUT = "mqScoreOutput"; 10. @Output(ProducerService.SCORE_OUPUT) 11. SubscribableChannel sendMessage(); 12. }</span>定义绑定1. <span style="font-size: 16px;">package com.honghu.cloud.producer; 3. import org.springframework.cloud.stream.annotation.EnableBinding; 5. @EnableBinding(ProducerService.class) 6. public class SendServerConfig { 8. }</span>定义发送音讯业务ProducerController1. <span style="font-size: 16px;">package com.honghu.cloud.controller; 4. import org.springframework.beans.factory.annotation.Autowired; 5. import org.springframework.integration.support.MessageBuilder; 6. import org.springframework.messaging.Message; 7. import org.springframework.web.bind.annotation.PathVariable; 8. import org.springframework.web.bind.annotation.RequestBody; 9. import org.springframework.web.bind.annotation.RequestMapping; 10. import org.springframework.web.bind.annotation.RequestMethod; 11. import org.springframework.web.bind.annotation.RestController; 13. import com.honghu.cloud.common.code.ResponseCode; 14. import com.honghu.cloud.common.code.ResponseVO; 15. import com.honghu.cloud.entity.User; 16. import com.honghu.cloud.producer.ProducerService; 18. import net.sf.json.JSONObject; 20. @RestController 21. @RequestMapping(value = "producer") 22. public class ProducerController { 24. @Autowired 25. private ProducerService producerService; 28. /** 29. * 通过get形式发送</span>对象<span > 30. * @param name 门路参数 31. * @return 胜利|失败 32. */ 33. @RequestMapping(value = "/sendObj", method = RequestMethod.GET) 34. public ResponseVO sendObj() { 35. User user = new User(1, "hello User"); 36. <span style="color: #ff0000;">Message<User> msg = MessageBuilder.withPayload(user).build();</span> 37. boolean result = producerService.sendMessage().send(msg); 38. if(result){ 39. return ResponseCode.buildEnumResponseVO(ResponseCode.RESPONSE_CODE_SUCCESS, false); 40. } 41. return ResponseCode.buildEnumResponseVO(ResponseCode.RESPONSE_CODE_FAILURE, false); 42. } 45. /** 46. * 通过get形式发送字符串音讯 47. * @param name 门路参数 48. * @return 胜利|失败 49. */ 50. @RequestMapping(value = "/send/{name}", method = RequestMethod.GET) 51. public ResponseVO send(@PathVariable(value = "name", required = true) String name) { 52. Message msg = MessageBuilder.withPayload(name.getBytes()).build(); 53. boolean result = producerService.sendMessage().send(msg); 54. if(result){ 55. return ResponseCode.buildEnumResponseVO(ResponseCode.RESPONSE_CODE_SUCCESS, false); 56. } 57. return ResponseCode.buildEnumResponseVO(ResponseCode.RESPONSE_CODE_FAILURE, false); 58. } 60. /** 61. * 通过post形式发送</span>json对象<span > 62. * @param name 门路参数 63. * @return 胜利|失败 64. */ 65. @RequestMapping(value = "/sendJsonObj", method = RequestMethod.POST) 66. public ResponseVO sendJsonObj(@RequestBody JSONObject jsonObj) { 67. Message<JSONObject> msg = MessageBuilder.withPayload(jsonObj).build(); 68. boolean result = producerService.sendMessage().send(msg); 69. if(result){ 70. return ResponseCode.buildEnumResponseVO(ResponseCode.RESPONSE_CODE_SUCCESS, false); 71. } 72. return ResponseCode.buildEnumResponseVO(ResponseCode.RESPONSE_CODE_FAILURE, false); 73. } 74. } 75. </span>创立commonservice-mq-consumer1音讯的消费者我的项目,在pom外面配置stream-rabbit的依赖1. <!-- 引入MQ音讯驱动的微服务包,引入stream只须要进行配置化即可,是对rabbit、kafka很好的封装 --> 2. <dependency> 3. <groupId>org.springframework.cloud</groupId> 4. <artifactId>spring-cloud-starter-stream-rabbit</artifactId> 5. </dependency>在yml文件中配置:1. server: 2. port: 5111 3. spring: 4. application: 5. name: commonservice-mq-consumer1 6. profiles: 7. active: dev 8. cloud: 9. config: 10. discovery: 11. enabled: true 12. service-id: commonservice-config-server 14. <span style="color: #ff0000;">stream: 15. bindings: 16. mqScoreInput: 17. group: honghu_queue 18. destination: honghu_exchange 19. contentType: application/json 21. rabbitmq: 22. host: localhost 23. port: 5672 24. username: honghu 25. password: honghu</span> 26. eureka: 27. client: 28. service-url: 29. defaultZone: http://honghu:123456@localhost:8761/eureka 30. instance: 31. prefer-ip-address: true定义接口ConsumerService1. package com.honghu.cloud.consumer; 3. import org.springframework.cloud.stream.annotation.Input; 4. import org.springframework.messaging.SubscribableChannel; 6. public interface ConsumerService { 8. <span style="color: #ff0000;">String SCORE_INPUT = "mqScoreInput"; 10. @Input(ConsumerService.SCORE_INPUT) 11. SubscribableChannel sendMessage();</span> 13. }定义启动类和音讯生产1. package com.honghu.cloud; 3. import org.springframework.boot.SpringApplication; 4. import org.springframework.boot.autoconfigure.SpringBootApplication; 5. import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6. import org.springframework.cloud.stream.annotation.EnableBinding; 7. import org.springframework.cloud.stream.annotation.StreamListener; 9. import com.honghu.cloud.consumer.ConsumerService; 10. import com.honghu.cloud.entity.User; 12. @EnableEurekaClient 13. @SpringBootApplication 14. @EnableBinding(ConsumerService.class) //能够绑定多个接口 15. public class ConsumerApplication { 17. public static void main(String[] args) { 18. SpringApplication.run(ConsumerApplication.class, args); 19. } 21. <span style="color: #ff0000;">@StreamListener(ConsumerService.SCORE_INPUT) 22. public void onMessage(Object obj) { 23. System.out.println("消费者1,接管到的音讯:" + obj); 24. }</span> 26. }别离启动commonservice-mq-producer、commonservice-mq-consumer1通过postman来验证音讯的发送和接管 ...

November 12, 2020 · 3 min · jiezi

关于spring:十六-整合spring-cloud云架构-使用spring-cloud-Bus刷新配置

咱们应用spring cloud散布式微服务云架构做了b2b2c的电子商务系统,除了架构自身自带的零碎服务外,咱们将b2b2c的业务服务进行了细粒度拆分,做成了不同的业务微服务。 当咱们的业务零碎越来越宏大简单的时候,各种配置也会随之增多。配置文件只有一批改,会对commonservice-config配置核心先进行服务,而后再重新启动,最初使配置失效。 如果服务少,咱们能够手动形式来启动,然而对业务和零碎的稳定性必定有肯定的影响。 如果是成千盈百的服务都靠手动操作,我预计运维人员或技术人员会疯掉的。 针对以上问题,commonservice-config服务端和业务微服务别离做了相干的配置,服务端负责将git(svn或本地文件系统)中存储的配置文件进行配置化(咱们应用的是本地配置计划,不便间接将配置文件更新到linux上), 业务微服务通过配置从服务端配置核心获取相干配置,如果配置文件变动了,通过刷新业务微服务的形式,将最新的配置信息获取。 spring cloud Bus通过一个轻量级音讯代理连贯分布式系统的节点。这能够用于播送状态更改(如配置更改)或其余治理指令。 接下来,咱们就来施行通过spring cloud Bus计划,动静刷新服务端配置,具体步骤如下: 1. commonservice-config服务配置能够参考之前的链接:http://2147775633.iteye.com/admin/blogs/2396692 2. 业务微服务配置(以honghu-member-servcie会员服务为例): pom文件配置: 1. <span style="font-size: 16px;"> <dependency> 2. <groupId>org.springframework.boot</groupId> 3. <artifactId><span style="font-size: 16px;">spring-boot-starter-actuator</span></artifactId> 4. </dependency> 6. <dependency> 7. <groupId>org.springframework.cloud</groupId> 8. <artifactId><span style="font-size: 16px;">spring-cloud-starter-bus-amqp</span></artifactId> 9. </dependency></span>yml文件配置: 1. <span style="font-size: 16px;">server: 2. port: 5012 3. spring: 4. application: 5. name: honghu-member-client 6. profiles: 7. active: dev,discoveryClient 8. cloud: 9. config: 10. discovery: 11. enabled: true 12. service-id: commonservice-config-server 13. <span style="font-size: 16px;"><strong>name: honghu-member 14. profile: dev 15. bus: 16. trace: 17. enabled: true #开启音讯跟踪  </strong> 18. <strong>rabbitmq: 19. host: 192.168.1.254 20. port: 5672 21. username: honghu 22. password: honghu</strong>  </span> 23. eureka: 24. client: 25. serviceUrl: 26. defaultZone: http://honghu:123456@localhost:8761/eureka/ 27. instance: 28. prefer-ip-address: true 29. logging: 30. level: 31. root: INFO 32. org.springframework.security: INFO 33. management: 34. security: 35. enabled: false 36. security: 37. basic: 38. enabled: false</span>编写一个测试类(MemberController.java),用来获取配置项 ...

November 12, 2020 · 1 min · jiezi

关于spring:重温Java泛型带你更深入地理解它更好的使用它

1. 引言jdk5.0中引入了Java泛型,目标是缩小谬误,并在类型上增加额定的形象层。本文将简要介绍Java中的泛型、泛型背地的指标以及如何应用泛型来进步代码的品质。 2. 为什么要用泛型?构想一个场景,咱们心愿用Java创立一个列表来存储Integer;代码可能会写成这样: List list = new LinkedList();list.add(new Integer(1)); Integer i = list.iterator().next();令人诧异的是,编译器会提醒最初一行。它不晓得返回的数据类型是什么。因而,编译器提醒须要进行显式转换: Integer i = (Integer) list.iterator.next();没有任何约定能够保障列表的返回类型是整数。定义的列表能够蕴含任何对象。咱们只晓得咱们是通过查看上下文来检索列表的。在查看类型时,它只能保障它是一个Object,因而须要显式转换来确保类型是平安的。 这种转换可能会令人感到聒噪,咱们明明晓得这个列表中的数据类型是整数。转换的话,也把咱们的代码搞得乌七八糟。如果程序员在显式转换中出错,则可能会导致抛出与 类型相干的运行时谬误 。 如果程序员可能表白他们应用特定类型的用意,并且编译器可能确保这种类型的正确性,那么这将更加容易。 这就是泛型背地的核心思想。 咱们将后面代码段的第一行批改为: List<Integer> list = new LinkedList<>();通过增加蕴含类型的菱形运算符<>,咱们将此列表的特化范畴放大到 Integer 类型,即指定将保留在列表中的类型。编译器能够在编译时强制执行该类型。 在较小的程序中,这看起来像是一个微不足道的增加。然而在较大的程序中,这能够减少显著的健壮性并使程序更易于浏览。 3. 泛型办法泛型办法是用单个办法申明编写的办法,能够用不同类型的参数调用。编译器将确保所用类型的正确性。以下是泛型办法的一些属性: 泛型办法在办法申明的返回类型之前有一个类型参数(包裹类型的菱形运算符)类型参数能够有界(边界将在本文前面解释)泛型办法能够具备不同的类型参数,这些参数在办法签名中用逗号分隔泛型办法的办法体与一般办法一样定义将数组转换为列表的泛型办法的示例: public <T> List<T> fromArrayToList(T[] a) { return Arrays.stream(a).collect(Collectors.toList());}在后面的示例中,办法申明中的 <T>示意该办法将解决泛型类型 T。即便办法返回的是void,也须要这样做。如上所述,办法能够解决多个泛型类型,在这种状况下,所有泛型类型都必须增加到办法申明中,例如,如果咱们要批改下面的办法来解决类型 T 和类型 G ,应该这样写: public static <T, G> List<G> fromArrayToList(T[] a, Function<T, G> mapperFunction) { return Arrays.stream(a) .map(mapperFunction) .collect(Collectors.toList());}咱们正在传递一个函数,该函数将具备T类型元素的数组转换为蕴含G类型元素的列表。例如,将 Integer 转换为其 String 示意模式: ...

November 12, 2020 · 2 min · jiezi

关于spring:VueSpring-Boot简单用户登录Demo

1 概述前后端拆散的一个简略用户登录Demo。 2 技术栈VueBootstrapVueKotlinSpring BootMyBatis Plus3 前端3.1 创立工程应用vue-cli创立,没装置的能够先装置: sudo cnpm install -g vue @vue/cli查看版本: vue -V呈现版本就装置胜利了。 创立初始工程: vue create bvdemo因为目前Vue3还没有公布正式版本,举荐应用Vue2: 期待一段时间构建好了之后会提醒进行文件夹并间接运行: cd bvdemoyarn serve间接通过本地的8080端口即可拜访: 3.2 依赖进入我的项目文件夹: cd bvdemo装置依赖: cnpm install bootstrap-vue axios jquery vue-router应该会呈现popper.js过期的正告,这是bootstrap-vue的起因,能够疏忽: 依赖阐明如下: bootstrap-vue:一个联合了Vue与Bootstrap的前端UI框架axios是一个简洁易用高效的http库,本我的项目应用其发送登录申请jquery:一个弱小的JS库vue-router:Vue的官网路由管理器3.3 开启补全在正式编写代码之前开启对bootstrap-vue的补全反对,关上设置: 将我的项目门路下的node_modules增加到库中,把后面的勾给勾上,接着更新缓存并重启(`File->Invalidate Cache/Restart`)。 3.4 App.vue去掉默认的HelloWorld组件,并批改App.vue如下: <template> <div id="app"> <router-view></router-view> </div></template><script>export default { name: 'App',}</script><style>#app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px;}</style><router-view>是一个functional组件,渲染门路匹配到的视图组件,这里应用<router-view>依据拜访门路(路由)的不同显示(渲染)相应的组件。 ...

November 12, 2020 · 3 min · jiezi

关于spring:spring-cloud构建分布式云架构微服务

1.鸿鹄Cloud框架选型-鸿鹄Cloud简介 鸿鹄Cloud应用大型互联网分布式企业微服务云架构(鸿鹄Cloud散布式微服务云),云框架是基于Spring Cloud来封装的,是一系列框架的有序汇合。利用Spring Boot的开发模式简化了分布式系统基础设施的开发,如服务发现、注册、配置核心、音讯总线、负载平衡、断路器、数据监控等(这里只简略的列了一部分),都能够用Spring Boot的开发格调做到一键启动和部署。鸿鹄云Cloud将目前比拟成熟、经得起理论考验的服务框架组合起来,通过Spring Boot格调进行再封装,屏蔽掉了简单的配置和实现原理,最终整合出一套简略易懂、易部署和易保护的分布式系统架构平台。 采纳服务化的组件开发模式,可实现简单的业务性能。提供驱动式开发模式,整合内置的代码生成器,将JavaEE开发效率进步5倍以上,缩小50%的代码开发量,解决80%的反复工作,让开发者更关注业务逻辑。 应用Maven进行我的项目的构建治理,采纳Jenkins进行继续集成,次要定位于大型分布式企业零碎或大型分布式互联网产品的架构。 2.鸿鹄技术架构 鸿鹄Cloud散布式微服务云联合了以后大部分企业的通用需要,包含技术的选型比拟严格、刻薄,不仅要用业界最风行的技术,还要和国内接轨,在将来的5~10年内不能out。为公司技术选型要有一种放眼世界的眼光,不仅要给公司做好的技术选型,而且还要疾速响应企业的业务需要,可能为企业疾速定制化业务。 鸿鹄Cloud应用大型互联网分布式企业微服务云架构(鸿鹄云),架构图如下: 3.鸿鹄Cloud组成 大型企业散布式微服务云架构服务组件实现模块化、微服务化、原子化、灰度公布、继续集成,组件组成如下: commonservice eureka 云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移 commonservice config 配置管理工具包,让你能够把配置放到近程服务器,集中化治理集群配置,目前反对本地存储、Git以及Subversion。 Spring Cloud Bus 事件、音讯总线,用于在集群(例如,配置变动事件)中流传状态变动,可与Spring Cloud Config联结实现热部署。 Hystrix 熔断器,容错管理工具,旨在通过熔断机制管制服务和第三方库的节点,从而对提早和故障提供更弱小的容错能力。 Feign Feign是一种申明式、模板化的HTTP客户端。 Spring Cloud Task 提供云端打算工作治理、任务调度。 Ribbon 提供云端负载平衡,有多种负载平衡策略可供选择,可配合服务发现和断路器应用。 Turbine Turbine是聚合服务器发送事件流数据的一个工具,用来监控集群下hystrix的metrics状况。 Zuul Zuul 是在云平台上提供动静路由,监控,弹性,平安等边缘服务的框架。Zuul 相当于是设施和 Netflix 流利用的 Web 网站后端所有申请的前门。 Spring Cloud Security 基于spring security的平安工具包,为你的应用程序增加安全控制。 commonservice sso 为Web、手机、PC提供对立登录、认证、受权入口,容许第三方零碎在用户受权的前提下拜访用户在服务鸿鹄云商存储的服务信息。 commonservice apigateway API网关封装了零碎外部架构,为每个客户端提供一个定制的API。如身份验证、监控、负载平衡、缓存、治理、动态响应解决。 commonservice zipkin 日志收集工具包,封装了Dapper和log-based追踪以及Zipkin和HTrace操作,为SpringCloud利用实现了一种分布式追踪解决方案。 commonservice turbine 聚合服务器发送事件流数据的一个工具,用来监控集群下hystrix的metrics状况。。 commonservice cache ...

November 11, 2020 · 1 min · jiezi

关于spring:看完了这篇面试的时候人人都能单手撸冒泡排序

鸡汤给大家备好了: 岁月流逝是如许残暴啊,对咱们也是如此,不要把工夫节约在不重要的人和事件上! 在计算机科学中,排序是一个经典的主题。学习排序算法的益处有三: 1.创造性解决问题 2.练习和坚固程序设计技能 3.演示算法性能的极好例子 冒泡排序属于比较简单的一种排序办法。然而,很多同学到当初也不能手写一个冒泡排序。甚至通过和一些刚毕业甚至工作一两年的敌人交换后,发现他们心田对算法,抱着深深的恐怖和盲目崇拜,感觉算法如同遥不可及,只适宜那些高学历、高智商的人来学习和钻研!明天,我想把这篇献给他们,心愿他们能建立起学习的勇气和信念! 1.什么是冒泡排序冒泡排序算法须要遍历几次数组,在每次遍历中,比拟间断相邻的元素。如果一对元素是降序排列,则调换他们的地位,否则放弃不变。这样一来,使得较小的值像“气泡”一样,逐步浮向顶部,而较大的值沉入底部,因而称这种排序办法为冒泡排序(bubble sort )或下沉排序(sinking sort)。 第一次遍历之后,最初一个元素将成为最大的元素。第二次遍历之后,倒数第二个元素,将成为倒数第二大的元素。整个过程继续到所有的元素全副都已排好序。 2.图解冒泡排序通过第一次遍历后,最大的数曾经在数组开端。因为最初一个数曾经是最大数,因而不须要再思考最初一对元素。 通过第二次遍历,后两个数曾经排好序,所以只须要对除它们之外的元素进行排序。 因而,在进行第n次遍历时,不须要思考倒数第n-1个元素,因为它们曾经排好序了! 冒泡排序伪代码: for(int k = 1; k < list.length; k++){ for(int j = 0; j < list.length-k; j++) { if(list[j] > list[j + 1]) { swap(list[i], list[i + 1]); } }}3.改良后的冒泡排序留神到,下面的排序实际上有很屡次没有产生替换,因而,咱们能够对冒泡排序略微改良下: boolean nextPass = true;for(int k = 1; k < list.length && nextPass; k++){ nextPass = false; for(int j = 0; j < list.length-k; j++) { if(list[j] > list[j + 1]) { swap(list[i], list[i + 1]); nextPass = true; } }}4. 冒泡排序工夫复杂度最佳状况下,冒泡排序只须要一次遍历就能确定数组已排好序,不须要再进行下一次遍历。因而,最佳状况下,冒泡排序工夫复杂度为O(n)。 ...

November 11, 2020 · 1 min · jiezi

关于spring:expected-at-least-1-bean-which-qualifies-as-autowire-candidate

在启动spring上下文进行junit单元测试时遇到了此谬误,网上找了很久都跟我的不一样,残缺的异样信息如下: 2020-11-10 22:43:09.217 [main-135] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.2020-11-10 22:43:09.764 [main-109] DEBUG org.apache.ibatis.io.VFS - Class not found: org.jboss.vfs.VFS2020-11-10 22:43:09.765 [main-142] DEBUG org.apache.ibatis.io.JBoss6VFS - JBoss 6 VFS API is not available in this environment.2020-11-10 22:43:09.767 [main-109] DEBUG org.apache.ibatis.io.VFS - Class not found: org.jboss.vfs.VirtualFile2020-11-10 22:43:09.769 [main-70] DEBUG org.apache.ibatis.io.VFS - VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.2020-11-10 22:43:09.771 [main-84] DEBUG org.apache.ibatis.io.VFS - Using VFS adapter org.apache.ibatis.io.DefaultVFS2020-11-10 22:43:12.696 [main-246] ERROR org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@e041f0c] to prepare test instance [com.star.service.impl.RedisTest@6a175569]org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.star.service.impl.RedisTest': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'boolean' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)} at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:321) ~[spring-context-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:400) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) ~[spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) ~[spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:242) [spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227) [spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) [spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.13.jar:4.13] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) [spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246) [spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) [spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) [junit-4.13.jar:4.13] at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) [junit-4.13.jar:4.13] at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) [junit-4.13.jar:4.13] at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) [junit-4.13.jar:4.13] at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) [junit-4.13.jar:4.13] at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) [junit-4.13.jar:4.13] at org.junit.runners.ParentRunner.run(ParentRunner.java:413) [junit-4.13.jar:4.13] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) [spring-test-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.13.jar:4.13] at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) [junit-rt.jar:?] at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) [junit-rt.jar:?] at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230) [junit-rt.jar:?] at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58) [junit-rt.jar:?]Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'boolean' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1504) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1101) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:506) ~[spring-context-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:484) ~[spring-context-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:618) ~[spring-context-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:177) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:318) ~[spring-context-5.0.2.RELEASE.jar:5.0.2.RELEASE] ... 26 moreorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.star.service.impl.RedisTest': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'boolean' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)} at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:321) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:400) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:242) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'boolean' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1504) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1101) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:506) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:484) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:618) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:177) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:318) ... 26 more本次谬误是因为我的BaseTest类遗记去掉一个之前加的无用注解@Resource,导致注入的时候找不到这个bean,因为我的所有单元测试类都继承这个类,所以导致其余的单元测试类都不能失常测试。不过网络上的答案也八九不离十,反正都是配置或者注解有误。呈现此类依赖注入谬误思考以下几点:1.注解是否增加全面,比方@Service,@Repository等。2.是否可能依赖循环注入?例如两个service相互注入等等。3.没有增加扫描包的标签? ...

November 10, 2020 · 2 min · jiezi

关于spring:Spring-Cloud关注者总结

鸿鹄云 Cloud 是基于 Spring Cloud 来封装的,是一系列框架的有序汇合。 利用 Spring Boot 的开发模式简化了分布式系统基础设施的开发,如服务发现、 注册、配置核心、音讯总线、负载平衡、断路器、数据监控等(这里只简略的列 了一部分),都能够用 Spring Boot 的开发格调做到一键启动和部署。鸿鹄云 Cloud 将目前比拟成熟、经得起理论考验的服务框架组合起来,通过 Spring Boot 格调进行再封装,屏蔽掉了简单的配置和实现原理,最终整合出一套简略易懂、 易部署和易保护的分布式系统架构平台。 Spring Cloud关注者总结,知识点有些曾经造成了文档,欢送各位喜爱学习的敌人下载!! 01鸿鹄Cloud散布式微服务云零碎-简介.pdf (206.2 KB)下载次数: 9102鸿鹄Cloud散布式微服务云零碎-技术点.pdf (130.9 KB)下载次数: 5103鸿鹄Cloud散布式微服务云零碎-组件化.pdf (175.4 KB)下载次数: 4504鸿鹄Cloud散布式微服务云零碎-架构图.pdf (251.4 KB)下载次数: 4505鸿鹄Cloud散布式微服务云零碎-代码构造.pdf (169.2 KB)下载次数: 4406鸿鹄Cloud散布式微服务云零碎-commonservice-eureka注册核心.pdf (506.6 KB)下载次数: 4007鸿鹄Cloud散布式微服务云零碎-commonservice-config配置服务.pdf (262.3 KB)下载次数: 3408鸿鹄Cloud散布式微服务云零碎-commonservice-system系统管理.pdf (970.4 KB)下载次数: 47

November 10, 2020 · 1 min · jiezi

关于spring:spring扫描自定义注解对应的类并装入IOC容器

前言本文继笔者学习mybatis源码后,仿照mybatis利用spring的拓展点将Mapper接口的代理类装入IOC的办法,实现自定义注解,让spring将指定包中有此注解的类拆卸进IOC容器来治理之,最终是放入容器的单例池中。 实现1. 自定义注解@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface XxgComponent {}2. XxgComponentScannerConfigurer2.1 实现BeanDefinitionRegistryPostProcessorBeanDefinitionRegistryPostProcessor,是spring给咱们的一个拓展点,其本身继承自BeanFactoryPostProcessor接口。实现此接口的类,spring在初始化之后,会调用其以下两个办法: void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;故咱们能够在其实现类对应的办法中,执行咱们的业务逻辑--即让spring扫描咱们自定义注解对应的类。 2.2 代码public class XxgComponentScannerConfigurer implements BeanDefinitionRegistryPostProcessor { private String basePackages; public void setBasePackages(String basePackages) { this.basePackages = basePackages; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException { // left intentionally blank } @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { XxgComponentScanner scanner = new XxgComponentScanner(registry); scanner.registerFilters(); scanner.scan(basePackages); }}3.扫描类XxgComponentScanner3.1 ClassPathBeanDefinitionScanner此类是spring用于扫描bean的类, ...

November 9, 2020 · 1 min · jiezi

关于spring:AQS源码深入分析之条件队列你知道Java中的阻塞队列是如何实现的吗

本文基于JDK-8u261源码剖析 1 简介 因为CLH队列中的线程,什么线程获取到锁,什么线程进入队列排队,什么线程开释锁,这些都是不受咱们管制的。所以条件队列的呈现为咱们提供了主动式地、只有满足指定的条件后能力线程阻塞和唤醒的形式。对于条件队列首先须要阐明一些概念:条件队列是AQS中除了CLH队列之外的另一种队列,每创立一个Condition实际上就是创立了一个条件队列,而每调用一次await办法实际上就是往条件队列中入队,每调用一次signal办法实际上就是往条件队列中出队。不像CLH队列上节点的状态有多个,条件队列上节点的状态只有一个:CONDITION。所以如果条件队列上一个节点不再是CONDITION状态时,就意味着这个节点该出队了。须要留神的是,条件队列只能运行在独占模式下。 个别在应用条件队列作为阻塞队列来应用时都会创立两个条件队列:notFull和notEmpty。notFull示意当条件队列已满的时候,put办法会处于期待状态,直到队列没满;notEmpty示意当条件队列为空的时候,take办法会处于期待状态,直到队列有数据了。 而notFull.signal办法和notEmpty.signal办法会将条件队列上的节点移到CLH队列中(每次只转移一个)。也就是说,存在一个节点从条件队列被转移到CLH队列的状况产生。同时也意味着,条件队列上不会产生锁资源竞争,所有的锁竞争都是产生在CLH队列上的。 其余一些条件队列和CLH队列之间的差别如下: 条件队列应用nextWaiter指针来指向下一个节点,是一个单向链表构造,不同于CLH队列的双向链表构造;条件队列应用firstWaiter和lastWaiter来指向头尾指针,不同于CLH队列的head和tail;条件队列中的第一个节点也不会像CLH队列一样,是一个非凡的空节点;不同于CLH队列中会用很多的CAS操作来管制并发,条件队列进队列的前提是曾经获取到了独占锁资源,所以很多中央不须要思考并发。上面就是具体的源码剖析了。条件队列以ArrayBlockingQueue来举例: 2 结构器 1 /** 2 * ArrayBlockingQueue: 3 */ 4 public ArrayBlockingQueue(int capacity) { 5 this(capacity, false); 6} 7 8 public ArrayBlockingQueue(int capacity, boolean fair) { 9 if (capacity <= 0)10 throw new IllegalArgumentException();11 //寄存理论数据的数组12 this.items = new Object[capacity];13 //独占锁应用ReentrantLock来实现(fair示意的就是偏心锁还是非偏心锁,默认为非偏心锁)14 lock = new ReentrantLock(fair);15 //notEmpty条件队列16 notEmpty = lock.newCondition();17 //notFull条件队列18 notFull = lock.newCondition();19 }3 put办法 1 /** 2 * ArrayBlockingQueue: 3 */ 4 public void put(E e) throws InterruptedException { 5 //非空校验 6 checkNotNull(e); 7 final ReentrantLock lock = this.lock; 8 /* 9 获取独占锁资源,响应中断模式。其实现代码和lock办法还有Semaphore的acquire办法是相似的 10 因为这里剖析的是条件队列,于是就不再剖析该办法的细节了 11 */ 12 lock.lockInterruptibly(); 13 try { 14 while (count == items.length) 15 //如果数组中数据曾经满了的话,就在notFull中入队一个新节点,并阻塞以后线程 16 notFull.await(); 17 //增加数组元素并唤醒notEmpty 18 enqueue(e); 19 } finally { 20 //开释锁资源 21 lock.unlock(); 22 } 23 }4 await办法如果在put的时候发现数组已满,或者在take的时候发现数组是空的,就会调用await办法来将以后节点放入条件队列中: ...

November 9, 2020 · 5 min · jiezi

关于spring:Spring-MVCMybatiscms实现UC浏览器文章相关功能

最近公司在模仿UC浏览器做一个简略的cms零碎,次要针对于企业外部的文章浏览需要,这边思考用户大多用mobile浏览文章内容,故应用原生的ios和android进行开发,前面也会集成html5。 应用前后端拆散解决方案(服务化的形式)文章分为一般类型、视频类型、图文类型浏览详情相干文章文章浏览统计个性化频道文章评论用户登录、注册、第三方登录我的珍藏文章分享到微信、qq这边性能就不一一列了,间接上图: 到此结束,前期我会把技术解决方案和代码贴出来供大家学习!(企业架构源码能够加求球:叁五三陆二肆柒二伍玖)

November 9, 2020 · 1 min · jiezi

关于spring:5分钟GET我使用Github-5-年总结的这些骚操作

我应用 Github 曾经有 5 年多了,明天毫无保留地把本人感觉比拟有用的 Gihub 小技巧送给关注 JavaGuide 的各位小伙伴。 这篇文章肝了很久,就挺用心的,大家看内容就晓得了。 如果感觉有播种的话,不要白嫖!点个赞/在看就是对我最大的激励。你要是能够三连(点赞+在看+转发)的话,我就更爽了(_我在想屁吃?_)。 1. 一键生成 Github 简历通过 http://resume.github.io/ 这个网站你能够一键生成一个在线的 Github 简历。 过后我加入的校招的时候,个人信息那里就放了一个在线的 Github 简历。我感觉这样会让面试官感觉你是一个外行,会进步一些印象分。 然而,如果你的 Github 没有什么我的项目的话还是不要放在简历外面了。生成后的成果如下图所示。 2. 个性化 Github 首页Github 目前反对在个人主页自定义展现一些内容。展现成果如下图所示。 想要做到这样非常简单,你只须要创立一个和你的 Github 账户同名的仓库,而后自定义README.md的内容即可。 展现在你主页的自定义内容就是README.md的内容(_不会 Markdown 语法的小伙伴自行面壁 5 分钟_)。 这个也是能够玩出花来的!比如说:通过 github-readme-stats 这个开源我的项目,你能够 README 中展现动静生成的 GitHub 统计信息。展现成果如下图所示。 对于个性化首页这个就不多提了,感兴趣的小伙伴自行钻研一下。 3. 自定义我的项目徽章你在 Github 上看到的我的项目徽章都是通过 https://shields.io/ 这个网站生成的。我的 JavaGuide 这个我的项目的徽章如下图所示。 并且,你不光能够生成动态徽章,shield.io 还能够动静读取你我的项目的状态并生成对应的徽章。 生成的形容我的项目状态的徽章成果如下图所示。 4. Github 表情 ...

November 9, 2020 · 1 min · jiezi

关于spring:springmvc详解3请求分发流程之拦截器-HandlerInterceptor

前言当Servlet接管到申请后会最终调用doDispatch办法后会去找到对应的HandlerMapping,同时也会找到配置的拦截器,最终组成须要的HandlerExecutionChain执行链(这里省略局部代码保留次要性能): protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { // 1.确定应用的handler HandlerExecutionChain mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // 确定handler的适配器 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 拦截器前置调用 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // 理论调用 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 设置默认视图名 applyDefaultViewName(processedRequest, mv); // 拦截器后置调用 mappedHandler.applyPostHandle(processedRequest, response, mv); // 散发后果 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); }拦截器在开发中拦截器的应用是比拟频繁的,例如用户拦截器,权限拦截器等。sringmvc的拦截器提供了pre,post,after三种期间的办法(调用处理器办法前,调用后,返回数据后),十分不便的进行资源设置,开释等性能。 public interface HandlerInterceptor { // 前 default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } // 中 default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } // 后 default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { }}拦截器注册当初看看拦截器是怎么注册的?spring提供两种形式。 ...

November 7, 2020 · 1 min · jiezi

关于spring:这个项目可以让你在几分钟快速了解某个编程语言

作为程序员,编程语言就是咱们建造程序世界的物料。学习编程第一步就是抉择一门适宜本人的编程语言。 然而,编程语言的品种太多了,像 Python、Java、Go、C++、JS等等都是目前比拟热门的编程语言。咱们的痛点是无奈疾速理解某个编程语言来搞清楚这个编程语言是否适宜本人。 有没有什么方法让咱们疾速理解一个编程语言的语言呢? 答案是有的! Github 有一个 叫做 learnxinyminutes-docs 的开源我的项目能够帮忙你X分钟疾速理解某个编程语言。 我的项目的 Github 地址:https://github.com/adambard/learnxinyminutes-docs 。我的项目配套的在线网站地址:https://learnxinyminutes.com/ 。上面这张图就是这个我的项目配套的网站。不要看着下面都是英文就胆怯了!这个我的项目提供的大部分编程语言的解说教程都有对应的中文翻译版本。 如果你的英语还不错的话,还是举荐你间接看英文版本,这样会原滋原味一些。 你还能够将中文版本(zh-cn)的解说给 highlight 进去。如下图所示。 如果咱们要疾速理解某个编程语言的话,很简略,间接在网站主页找到这门编程语言即可。 我这里拿Go语言来举一下例子(Go语言这段时间比拟火)。 咱们想要疾速理解 Go 语言的话,间接在网站主页找到 Go语言的中文版本即可。 关上之后,你会就会看到 go 语言对应的入门教程了。 我不敢说这个入门教程写的有多好,然而,的确是把一门编程语言大部分比拟重要的点都提了一下。 比方 go 语言教程这里写到:http 包中的一个简略的函数就能够开启web服务器。 // http包中的一个简略的函数就能够开启web服务器。func learnWebProgramming() { // ListenAndServe第一个参数指定了监听端口,第二个参数是一个接口,特定是http.Handler。 go func() { err := http.ListenAndServe(":8080", pair{}) fmt.Println(err) // 不要忽视谬误。 }() requestServer()}确实,每一个程序员都须要有一门比拟相熟的编程语言作为本人的武器。 然而,这并不代表咱们不须要理解其余编程语言。 编程语言只是工具。 抉择适合的编程语言做适合的事件很重要。 比方 Java 适宜网站开发而 Python 更适宜做数据分析。 再比方你想要做全栈开发的话,还可能须要把握多门编程语言。拿我本人来说,也算是半个全栈开发,我次要是以 Java 做后端开发,Javascript 来进行前端开发。 ...

November 6, 2020 · 1 min · jiezi

关于spring:一起来读官方文档SpringIOC11

1.13。EnvironmentEnvironment接口是集成在容器中的形象存在,它体现为应用程序环境的两个要害方面:profiles和properties。 1.13.1。Bean Definition ProfilesBean Definition Profiles在外围容器中提供了一种机制,该机制容许在不同environment中注册不同的Bean。 说白了其实就是判断 spring.profiles.active 的值这个值能够有多个两头用 , 隔开就能够“environment”一词对不同的用户而言可能意味着不同的含意,并且此性能能够在许多用例中提供帮忙,包含: 在开发中针对内存中的数据源进行工作,而不是在进行QA或生产时从JNDI查找雷同的数据源。仅在将应用程序部署到性能环境中时注册监督根底构造。为客户A和客户B部署注册bean的自定义实现。思考理论利用中须要应用的第一个用例DataSource。 在测试环境中,配置可能相似于以下内容: @Beanpublic DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.HSQL) .addScript("my-schema.sql") .addScript("my-test-data.sql") .build();}当初,假如该应用程序的数据源已在生产应用程序服务器的JNDI目录中注册,请思考如何将该应用程序部署到QA或生产环境中。 当初,咱们的dataSource bean看起来像上面的清单: @Bean(destroyMethod="")public DataSource dataSource() throws Exception { Context ctx = new InitialContext(); return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");}问题是如何依据以后环境在应用这两种变体之间进行切换。 随着工夫的流逝,Spring用户曾经设计出许多办法来实现此工作,通常依赖于零碎环境变量和<import/>蕴含${placeholder}的XML语句的组合,这些${placeholder}依据环境变量的值解析为正确的配置文件门路。 Bean Definition Profiles是一项外围容器性能,可提供此问题的解决方案。 应用 @Profile@Profile注解能做到只有在您指定的一个或多个指定的概要文件处于活动状态时才对该组件进行注册。 应用后面的示例,咱们能够重写数据源配置,如下所示: @Configuration@Profile("development")public class StandaloneDataConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.HSQL) .addScript("classpath:com/bank/config/sql/schema.sql") .addScript("classpath:com/bank/config/sql/test-data.sql") .build(); }}@Configuration@Profile("production")public class JndiDataConfig { @Bean(destroyMethod="") public DataSource dataSource() throws Exception { Context ctx = new InitialContext(); return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource"); }}如前所述,对于@Bean办法,您通常抉择应用编程式JNDI查找,办法是应用Spring的JNDIMplate/JNDilocatorDeleteGate帮忙器,或者应用后面显示的间接JNDIInitialContext用法,而不是JndiObjectFactoryBean变量,因为factoryBean办法返回的是FactoryBean类型,而不是DataSource类型。原理解释:1.@Profile注解中指定了@Conditional注解中的ProfileCondition.class@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@Conditional(ProfileCondition.class)public @interface Profile { /** * The set of profiles for which the annotated component should be registered. */ String[] value();}2.首先在加载bean的时候发现有办法判断是否应该调过以后beanif (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) { configClass.skippedBeanMethods.add(methodName); return;}在shouldSkip中会查问以后bean的所有的condition并循环执行每个condition的matches而@Profile的condition的matches如下所示class ProfileCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName()); if (attrs != null) { for (Object value : attrs.get("value")) { //此处 调用了environment的propertySources //判断以后配置中的所有的propertySources是否含有spring.profiles.active属性 //有值的话就将它设置到environment的activeProfiles属性中 //再判断以后类的@Profile注解中的值是否被蕴含在activeProfiles属性内 //如果被蕴含则返回true if (context.getEnvironment().acceptsProfiles(Profiles.of((String[]) value))) { return true; } } return false; } return true; }}配置文件字符串能够蕴含简略的配置文件名称(例如production)或配置文件表达式。 配置文件表达式容许表白更简单的配置文件逻辑(例如production & us-east)。 概要文件表达式中反对以下运算符: ...

November 5, 2020 · 6 min · jiezi

关于spring:拦截器过滤器切面比较

1. 切面1.1. 切片(类) @Aspect@AspectUserController.*(..) 1.2. 切入点(注解) @AroundAround("execution(* com.niewj.controller.)")1.3 加强(办法)public Object process(ProceedingJointPoint pjp){ // 调用前 Object o = pjp.proceed(); // 1. 调用原办法 // 调用后 Object[] args = pjp.getArg(); // 2. 拿参数 for(Object arg:args){ System.out.println("arg is: "+ arg) }}2. 拦截器实现HandlerInterceptor接口继承HandlerInterceptorAdapter类2.1 preHandler@Overridepublic boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler // Object-> HandlerMethod ) throws Exception { return true;}Controller的办法被解决之前, preHandler会被调用;2.2 postHandler@Overridepublic void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, // Object-> HandlerMethod ModelAndView modelAndView ) throws Exception {}Controller的办法被解决之后, postHandle会被调用, 但有个前提: ...

November 5, 2020 · 1 min · jiezi

关于spring:搭建一个以Spring-Framework为容器的基础应用

1、创立一个Maven构造的利用IDEA创立我的项目时抉择maven我的项目 2、pom.xml中增加一下依赖<?xml version="1.0" encoding="UTF-8"?><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"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>common</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.10.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.10.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build></project>3、创立Spring配置文件service.xml在这里能够找到Spring官网给的样例。上面是我运行失常的配置。 <?xml version="1.0" encoding="UTF-8"?><!-- ~ Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. --><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mysql?useUnicode=true&amp;characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <context:component-scan base-package="entity"/></beans>4、编写须要Spring治理的Bean和main办法治理的Bean这里就省略了,main办法代码如下: ...

November 5, 2020 · 1 min · jiezi

关于spring:十四-整合spring-cloud云架构-Spring-Cloud构建分布式电子商务平台

通过Spring Cloud构建PC+微信+APP+云服务的云商平台零碎,其中包含B2B、B2C、C2C、O2O、新批发、直播电商等子平台,之前咱们讲了很多对于Spring Cloud的概念文章,从本节开始,咱们会以散布式微服务电子商务平台为案例,逐渐给大家解说如何构建残缺的电子商务云平台。 技术解决方案 开发语言: java 数据库:mysql JDK反对版本: JDK1.8 核心技术:分布式、云服务、微服务、服务编排 外围架构: 应用Spring Cloud散布式微服务云架构进行服务化开发,所有模块性能齐全解耦,提供服务发现、注册、配置核心、音讯总线、负载平衡、断路器、数据监控等。 技术列表: Spring Cloud Config配置管理工具包,让你能够把配置放到近程服务器,集中化治理集群配置,目前反对本地存储、Git以及Subversion Spring Cloud Bus事件、音讯总线,用于在集群(例如,配置变动事件)中流传状态变动,可与Spring Cloud Config联结实现热部署 Eureka云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。 Hystrix熔断器,容错管理工具,旨在通过熔断机制管制服务和第三方库的节点,从而对提早和故障提供更弱小的容错能力。 ZuulZuul 是在云平台上提供动静路由,监控,弹性,平安等边缘服务的框架。Zuul 相当于是设施和 Netflix 流利用的 Web 网站后端所有申请的前门。 Spring Cloud Security基于spring security的平安工具包,为你的应用程序增加安全控制。 FeignFeign是一种申明式、模板化的HTTP客户端。 通用架构: Spring Boot,Spring Cloud,Spring MVC,Spring security,Oauth2.0,Mybatis plus  技术架构图:   代码结构图:   APP界面截图:       后盾治理截图:        从当初开始,我这边会将近期研发的spring cloud微服务云架构的搭建过程和精华记录下来,帮忙更多有趣味研发spring cloud框架的敌人,大家来一起探讨spring cloud架构的搭建过程及如何使用于企业我的项目。

November 5, 2020 · 1 min · jiezi

关于spring:给字节的学姐讲如何准备系统设计面试

零碎设计在面试中肯定是最让面试者头疼的事件之一。 因为零碎设计相干的问题通常是开放式的,所以没有标准答案。你在和面试官思维的交换碰撞中会缓缓优化本人的零碎设计方案。实践上来说,零碎设计面试也是和面试官一起一步一步改良原有零碎设计方案的过程。 零碎设计题往往也十分能考查出面试者的综合能力,答复好的话,很容易就能在面试中怀才不遇。不论是对于加入社招还是校招的小伙伴,都很有必要器重起来。 接下来,我会带着小伙伴们从我的角度登程来谈谈:如何筹备面试中的零碎设计局部。 因为文章篇幅无限,就不列举理论例子了,可能会在前面的文章中独自提一些具体的例子。 集体能力无限。如果文章有任何须要改善和欠缺的中央,欢送在评论区指出,共同进步! 零碎设计面试个别怎么问?我简略总结了一下零碎设计面试相干问题的问法: 设计一个某某零碎比方秒杀零碎、微博零碎、抢红包零碎、短网址零碎。设计某某零碎中的一个性能比方哔哩哔哩的点赞性能。设计一个框架比方 RPC 框架、音讯队列、缓存框架、分布式文件系统等等。某某零碎的技术选型比方缓存用Redis 还是 Memcached、网关用 Spring Cloud Gateway 还是 Netflix Zuul2 。零碎设计怎么做?咱们将步骤总结成了以下 4 步。 Step1:问分明零碎具体要求当面试官给出了零碎设计题目之后,肯定不要立刻开始设计解决方案。 你须要先了解零碎设计的需要:功能性需要和非功能性需要。 为了防止本人误解题目所想要解决的问题,你能够先简要地给面试官说说本人的了解, 为啥要询问分明零碎的功能性需要也就是说零碎蕴含哪些性能呢? 毕竟,如果面试官冷不丁地间接让你设计一个微博零碎,你不可能把微博零碎涵盖的性能比方举荐信息流、会员机制等一个一个都列举进去,而后再去设计吧!你须要筛选出零碎所提供的外围性能(放大边界范畴)! 为啥要询问分明零碎的非功能性需要或者说约束条件比方零碎须要达到多少QPS呢? 让你设计一个1w人用的微博零碎和100w人用的微博零碎能一样么?不同的束缚零碎对应的零碎设计方案必定是不一样的。 Step2:对系统进行形象设计咱们须要在一个 High Level 的层面对系统进行设计。 你能够画出零碎的形象架构图,这个形象架构图中蕴含了零碎的一些组件以及这些组件之间的连贯。 Step3:思考零碎目前须要优化的点对系统进行形象设计之后,你须要思考以后形象的零碎设计有哪些须要优化的点,比如说: 以后零碎部署在一台机器够吗?是否须要部署在多台机器而后进行负载平衡呢?数据库处理速度是否撑持业务需要?是否须要给指定字段加索引?是否须要读写拆散?是否须要缓存?数据量是否大到须要分库分表?是否存在安全隐患?零碎是否须要分布式文件系统?......Step4:优化你的零碎形象设计依据 Step 3 中的“零碎须要优化的点” 对系统的形象设计做进一步欠缺。 零碎设计该如何筹备?常识储备零碎设计面试十分考查你的常识储备,零碎设计能力的进步须要大量的理论知识储备。比如说你要晓得大型网站架构设计必备的三板斧: 高性能架构设计: 相熟零碎常见性能优化伎俩比方引入 读写拆散、缓存、负载平衡、异步 等等。高可用架构设计 :CAP实践和BASE实践、通过集群来进步零碎整体稳定性、超时和重试机制、应对接口级故障:降级、熔断、限流、排队。高扩大架构设计 :说白了就是懂得如何拆分零碎。你依照不同的思路来拆分软件系统,就会失去不同的架构。实战尽管懂得了实践,然而本人没有进行实际的话,很多货色是无奈领会到的! 因而,你还要 一直通过实战我的项目锤炼本人的零碎设计能力。 放弃好奇心多思考本人常常浏览的网站是怎么做的。比方: 你刷微博的时候能够思考一下微博是如何记录点赞数量的?你看哔哩哔哩的时候能够思考一下音讯揭示零碎是如何做的?你应用短链零碎的时候能够考虑一下短链零碎是如何做的?......技术选型实现同样的性能,个别会有多种技术抉择计划,比方缓存用Redis 还是 Memcached、网关用 Spring Cloud Gateway 还是 Netflix Zuul2 。 很多时候,面试官在零碎设计面过程中会具体到技术的选型,因此,你须要辨别不同技术的优缺点。 零碎设计面试必知零碎设计的时候必然离不开形容性能相干的指标比方 QPS。性能相干的指标响应工夫响应工夫RT(Response-time)就是用户发出请求到用户收到零碎处理结果所须要的工夫。 RT是一个十分重要且直观的指标,RT数值大小间接反馈了零碎解决用户申请速度的快慢。 并发数并发数能够简略了解为零碎可能同时供多少人拜访应用也就是说零碎同时能解决的申请数量。 并发数反馈了零碎的负载能力。 ...

November 5, 2020 · 2 min · jiezi

关于spring:SpringAop重难点分析

重难点剖析AOP 是什么,解决了什么问题,利用场景?是什么?AOP:面向切面编程,可能在不扭转原有代码的状况下对代码的性能进行加强。 解决了什么问题?AOP 次要用来解决:在不扭转原有业务逻辑的状况下,加强横切逻辑代码,基本上解耦合,防止横切逻辑代码反复。可能解决代码的臃肿问题,进步代码的可维护性。 利用场景?次要利用于:日志记录,事务管制,性能统计,安全控制,异样解决等。 AOP 编程根本步骤及实现过程(以基于AspectJ框架实现为例)。1.增加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency>2.创立日志切面类对象(以日志为例) package com.cy.pj.common.aspect;@Aspect//示意此类对象为一个切面@Slf4j@Component//将此类交给spring治理public class SysLogAspect { @Pointcut("bean(sysUserServiceImpl)")//切入点 public void logPointCut() {} @Around("logPointCut()")//盘绕告诉,示意此办法在外围业务执行之前和之后执行 public Object around(ProceedingJoinPoint jp) throws Throwable{ try { log.info("start:{}"+System.currentTimeMillis()); Object result=jp.proceed();//最终会调用指标办法 log.info("after:{}"+System.currentTimeMillis()); return result; }catch(Throwable e) { log.error("after:{}",e.getMessage()); throw e; } }}3.测试 @SpringBootTestpublic class AopTests { @Autowired private SysUserService userService; @Test public void testSysUserService() { PageObject<SysUserDeptVo>po=userService.findPageObjects("admin",1); System.out.println("rowCount:"+po.getRowCount()); }}AOP 编程中的外围对象及利用关系。Aspect:切面,由一系列切点、加强和引入组成的模块对象,可定义优先级,从而影响加强和引入的执行程序。事务管理(Transaction management)在java企业应用中就是一个很好的切面样例。 Join point:接入点,程序执行期的一个点,例如办法执行、类初始化、异样解决。 在Spring AOP中,接入点始终示意办法执行。 Advice:加强,切面在特定接入点的执行动作,包含 “around,” “before” and "after"等多种类型。蕴含Spring在内的许多AOP框架,通常会应用拦截器来实现加强,围绕着接入点保护着一个拦截器链。 ...

November 5, 2020 · 1 min · jiezi

关于spring:十二-整合spring-cloud云架构-SSO单点登录之OAuth20-登出流程3

上一篇我依据框架中OAuth2.0的应用总结,画了一个依据用户名+明码实现OAuth2.0的登录认证的流程图,明天咱们看一下logout的流程: 1. /** 2. * 用户登记 3. * @param accessToken 4. * @return 5. */ 6. @RequestMapping(value = "/user/logout", method = RequestMethod.POST) 7. public ResponseVO userLogout(@RequestHeader(value = "accessToken", required = true) String accessToken, 8. @RequestHeader(value = "userId", required = true) Long userId) throws Exception{ 9. OauthAccessToken oauthAccessToken = userMgrService.getOauthAccessToken(accessToken); 10. if(null == oauthAccessToken){ 11. return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_CODE_OAUTH_ACCESSTOKEN_EMPTY, null); 12. } 13. //刪除OauthToken记录 14. boolean result = userMgrService.revokeOauthToken(oauthAccessToken); 15. if(result){ 16. return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_RETURN_CODE_SUCCESS, null); 17. } 18. return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_CODE_SYSTEM_ERROR, null); 19. }我这里只是简略写了一些登出的代码,咱们会在前面的文章中具体贴出所有代码供大家参考,而且会从创立数据库,到执行操作的每一个流程记录下来。(企业架构源码能够加求球:叁五三陆二肆柒二伍玖) 从当初开始,我这边会将近期研发的spring cloud微服务云架构的搭建过程和精华记录下来,帮忙更多有趣味研发spring cloud框架的敌人,大家来一起探讨spring cloud架构的搭建过程及如何使用于企业我的项目。

November 4, 2020 · 1 min · jiezi

关于spring:springboot注解描述

SpringBoot 中的根本注解@SpringBootApplication 注解任何一个我的项目都有一个入口,在SpringBoot启动类须要有@SpringBootApplication 注解进行蔑视,并且在类中定义一个main办法,main办法在运行时会读取配置文件,并加载指定资源,而后进行初始化操作.所以:SpringBoot 我的项目在启动是时,首选基于启动入口类上的注解形容,进行主动配置并扫描指定包以及子包中的类进行加载. @SpringBootTest 注解顾名思义 SpringBoot工程中的单元测试须要应用@SpringBootTest 注解进行形容,用于通知spring框架,次此测试类交由spring治理 @Autowired 注解简略来说,@Autowired 注解就是通知spring框架运行时为此属性注入一个值 例如: @SpringBootTestpublic class DefauleCacheTests { @Autiwired private DefaultCache defaultCache; @Test void test DefaultCache(){ System.out.println("defaultCache:"+ defaultCache); }输入后果为: defaultCache:com.cy.pj.common.cache.DefaultCache@6e33c391@Component 注解@Component 注解时Spring中用于形容Bean类的一个注解,用于通知Spring这个类的实例由Spring创立,当此对象有Spring治理和创立是,会默认将对象存储到池中(Bean池)中. @Scope 注解@Scpoe注解 是Spring中用于定义Bean对象作用域的一个注解 罕用的值有@Scope(singleton) @scpoe(prototype) @Scope(singleton):@Scope的默认值,单例作用域.既整个内存只有一份Bean实例,此实例创立与类提早加载个性配置无关(@Lazy),此实例创立后生命周期会由spring框架治理. @Scope(prototype): 多例作用域,每次获取都会创立新的实例,此实例会在须要的时创立,与Lazy个性无关,这个实例创立当前,并不会交给spring治理,spring能够对其初始化,但不负责销毁. @Lazy 注解@Lazy 注解用于形容类,其目标是通知Spring框架,此类反对提早加载通常配合单例作用域(@singleton)应用简略来说,就是它形容的类的实例,如果临时用不到,就不要先创立实例(@Lazy(true) 默认值,实用于大对象,稀少用) @PostConstruct 注解@PostConstruct 注解形容的办法会在对象构建当前执行,用于执行一些初始化操作 @PreDestroy 注解@PreDestroy 注解形容的办法会在单例对象销毁之前执行,spring容器在销毁之前,会先将容器(Bean)中的对象移除,在移除对象时,如果对象中定义了生命周期销毁办法,此时还会调用对象的生命周期销毁办法(在这样的办法中能够做一些资源开释操作) 总结@SpringBootApplication @SpringBootTest @Component@Lazy @scope 次要用于类上@PostConstruct @PreDestroy 次要用于办法上 @Lazy和@PreDestroy 能够与实用于单例作用域应用 @Scope(singleton),但不适用于多例作用域@Scope(prototype).Spring中的注解详说:Spring经验了如下几个阶段: 第一阶段:xml配置在Spring 1.x时代,应用Spring开发满眼都是xml配置的Bean,随着我的项目的扩充,咱们须要把xml配置文件放到不同的配置文件里,那时须要频繁的在开发的类和配置文件之间进行切换 第二阶段:注解配置在Spring 2.x 时代,随着JDK1.5带来的注解反对,Spring提供了申明Bean的注解(例如@Component、@Service),大大减少了配置量。次要应用的形式是利用的根本配置(如数据库配置)用xml,业务配置用注解 第三阶段:java配置Spring 3.0 引入了基于 Java 的配置能力,这是一种类型平安的可重构配置形式,能够代替 XML。咱们目前刚好处于这个时代,Spring4.x和Spring Boot都举荐应用Java配置。所有这些xml配置都代表了开发时的损耗。 因为在思考 Spring 个性配置和解决业务问题之间须要进行思维切换,所以写配置挤占了写利用程序逻辑的工夫。Spring Boot 让这所有成为了过来。Spring Boot 简化了基于Spring的利用开发,只须要“run”就能创立一个独立的、生产级别的Spring利用。Spring Boot为Spring平台及第三方库提供开箱即用的设置(提供默认设置),这样咱们就能够简略的开始。少数Spring Boot利用只须要很少的Spring配置。咱们能够应用SpringBoot创立java利用,并应用java –jar 启动它,或者采纳传统的war部署形式。这也是SpringBoot让越来越多的开发人员应用的次要起因之一。上面咱们就来具体解说SpringBoot几个很重要的注解:@Configuration , @Bean,@SpringBootApplication,@ComponentScan ...

November 4, 2020 · 1 min · jiezi

关于spring:一文搞懂什么是单代号网络图

项目管理之进度治理——单代号网络图1. 概念前导图法(Precedence Diagramming Method, PDM),也称之为紧前关系绘图法,是用于编制我的项目进度网络图的一种办法,它应用方框(称之为节点)代表流动,节点之间用箭头连贯,以显示节点之间的逻辑关系。这种网络图也被称作为单代号网络图(只有节点须要编号)或流动节点图(Active On Node, AON)。 前导图法包含流动之间存在4种类型的依赖关系,别离是: 1.完结-开始的关系(F-S型):前序流动完结后,后续流动能力开始。例如:只有较量(紧前流动)完结,颁奖地仪式(紧后流动)能力开始。 2.完结-完结的关系(F-F型):前序流动完结后,后续流动能力完结。例如:只有实现了文件的编写(紧前后动),能力实现文件的编辑(紧后流动) 3.开始-开始的关系(S-S型):前序流动开始后,后续流动能力开始。例如:开始播放伴奏后(紧前流动),能力开始演唱(紧后流动) 4.开始-完结的关系(S-F型):前序流动开始后,后续流动能力完结。例如:只有新版本零碎提供稳固服务后(紧前流动),旧版本零碎能力进行服务(紧后流动) 2.单代号网络图的特点:1、绘图简略,不须要用虚箭线,工作之间的逻辑关系比拟容易表白。 2、单代号网络图绝对于双代号网络图更便于检查和批改。 3、因为单代号网络图的工作持续时间示意在节点内,所以绝对不够形象、直观。 4、应用单代号网络图示意的工作间的逻辑关系,其箭线可能会产生较多的纵横穿插的景象。 5、当没有节点工夫参数时,不能画时标网络图。 3.单代号网络图绘制规定1、绘图中禁止呈现循环回路。 2、每个节点示意一项工作,所以各节点的代号不能反复。 3、绘图中禁止呈现双向箭头或者无箭头的连线。 4、应用数字示意工作的名称时,应由小至大按流动先后顺序进行编号。 5、绘图中禁止呈现没有箭尾节点的箭线和没有箭头节点的箭线。 6、绘图中,箭线不宜穿插,然而当穿插不可避免时,也能够采纳过桥法或指向法进行绘制。 7、在单代号网络途中,只有一个终点节点和一个起点节点。如果在网络图中有多项终点节点或多项起点节点,则应该在网络图的两端别离设置一项虚工作,作为该网络图的终点节点和起点节点。 8、除了终点节点和起点节点以外,其余所有的节点都应该有指向箭线和背向箭线。 9、在绘制网络图时,单代号和双代号的画法不能混用。 4.单代号网络图组成的根本元素:1、节点:示意的是工作,一个节点则示意一个工作。个别用圆圈或者矩形示意。在单代号网络图中节点必须进行编号,且标注在节点内,编号能够间断,然而与双代号网络图一样绝不能够反复。 2、箭线:示意的是工序之间的逻辑关系。箭线个别用程度直线、折线或者斜线来示意,程度投影时的方向应自左向右,示意的是工作进行的方向。 3、线路:在单代号网络途中,每条线路都应该用其该线路上的节点编号,按照从小到大的程序进行表述。 5. 绘制单代号网络图:图例1: 图例2: 图例3: 绘制一张单代号网络图: 看完这篇,单代号网络图,你会画了吗?留言通知我吧! 如果你感觉文章还不错,记得关注公众号: 锅外的大佬刘一手的博客

November 3, 2020 · 1 min · jiezi

关于spring:九整合spring-cloud云服务架构-commonserviceconfig配置服务搭建

介绍Spring Cloud Config为分布式系统中的内部配置提供服务器和客户端反对。应用Config Server,您能够在所有环境中管理应用程序的内部属性。客户端和服务器上的概念映射与Spring Environment和PropertySource形象雷同,因而它们与Spring应用程序十分符合,但能够与任何以任何语言运行的应用程序一起应用。随着应用程序通过从开发人员到测试和生产的部署流程,您能够治理这些环境之间的配置,并确定应用程序具备迁徙时须要运行的所有。服务器存储后端的默认实现应用git,因而它轻松反对标签版本的配置环境,以及能够拜访用于治理内容的各种工具。很容易增加代替实现,并应用Spring配置将其插入。(企业架构源码能够加求球:叁五三陆二肆柒二伍玖) 引入pom相干jar包,其中pom.xml配置如下:1. <?xml version="1.0" encoding="UTF-8"?> 2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4. <modelVersion>4.0.0</modelVersion> 6. <parent> 7. <groupId>com.ml.honghu</groupId> 8. <artifactId>commonservice</artifactId> 9. <version>0.0.1-SNAPSHOT</version> 10. </parent> 12. <artifactId>commonservice-config</artifactId> 13. <packaging>jar</packaging> 15. <name>commonservice-config</name> 16. <description>Config Server</description> 18. <dependencies> 19. <dependency> 20. <groupId>org.springframework.cloud</groupId> 21. <artifactId>spring-cloud-config-server</artifactId> 22. </dependency> 23. <dependency> 24. <groupId>org.springframework.cloud</groupId> 25. <artifactId>spring-cloud-starter-eureka</artifactId> 26. </dependency> 27. <dependency> 28. <groupId>org.springframework.boot</groupId> 29. <artifactId>spring-boot-starter-security</artifactId> 30. </dependency> 31. <dependency> 32. <groupId>org.springframework.boot</groupId> 33. <artifactId>spring-boot-starter-test</artifactId> 34. <scope>test</scope> 35. </dependency> 36. </dependencies> 38. <build> 39. <plugins> 40. <plugin> 41. <groupId>org.springframework.boot</groupId> 42. <artifactId>spring-boot-maven-plugin</artifactId> 43. <executions> 44. <execution> 45. <id>1</id> 46. <goals> 47. <goal>repackage</goal> 48. </goals> 49. </execution> 50. <execution> 51. <id>2</id> 52. <goals> 53. <goal>build-info</goal> 54. </goals> 55. </execution> 56. </executions> 57. </plugin> 58. </plugins> 59. </build> 60. </project>在src/main/java进行ConfigApplication.java启动文件配置:1. package com.ml.honghu; 3. import org.springframework.boot.SpringApplication; 4. import org.springframework.boot.autoconfigure.SpringBootApplication; 5. import org.springframework.cloud.config.server.EnableConfigServer; 6. import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 8. @EnableConfigServer 9. @EnableEurekaClient 10. @SpringBootApplication 11. public class ConfigApplication { 13. public static void main(String[] args) { 14. SpringApplication.run(ConfigApplication.class, args); 15. } 16. }在src/main/resource下进行bootstrap.yml配置1. server: 2. port: 8888 3. spring: 4. application: 5. name: commonservice-config-server 6. profiles: 7. active: discovery,native 8. cloud: 9. config: 10. server: 11. git: 12. uri: http://192.168.0.254/honghu.../honghu-config.git 13. username: honghu 14. password: 123456 15. searchPaths: config-dev 16. security: 17. basic: 18. enabled: true 19. user: 20. name: honghu 21. password: 123456 22. eureka: 23. client: 24. serviceUrl: 25. defaultZone: http://honghu:123456@localhost:8761/eureka/ 26. honghuZone: http://honghu:123456@localhost:8761/eureka/ 27. registry-fetch-interval-seconds: 300 28. availability-zones: 29. honghu: honghuZone 30. instance: 31. prefer-ip-address: true 32. metadataMap: 33. version: 1.0 34. variant: A 35. user: ${security.user.name} 36. password: ${security.user.password} 37. management: 38. security: 39. enabled: false留神: 如果不从近程git或者svn库加载配置文件信息,能够配置加载本地地址,比方window下配置应用: ...

November 2, 2020 · 2 min · jiezi

关于spring:Java-In-This-Week-打工人的一周

1. Spring and Java >> The JPA and Hibernate first-level cache [vladmihalcea.com] 对于JPA/Hibernate中第一级缓存的益处:写后缓存、批处理和应用程序级可反复读取。 >>Java模块化状态的更新 [blog.frankel.ch] 对Java生态系统中一些驰名图书馆采纳Java模块零碎的剖析。 >> 应用jEnv治理多个JDK装置 [reflectoring.io] 在解决多个Java版本时遇到了艰难?jEnv有助于在多个Java版本之间进行切换 也值得一读:>> JEP 396: 默认状况下,强封装JDK外部构件 [openjdk.java.net]>> 重温Gradle POMs [andresalmiray.com]>> Spring Cloud中的聚合性能和处理器 [spring.io]>> 通往 Jakarta EE 9 [infoq.com]>> Just AI推出了基于Kotlin的开源会话框架 [infoq.com]网络研讨会和演示: >>Brian Goetz的谈Java将来 [inside.java]>> Joe Darcy 和 Erik Duveblad:第六期 “Project Skara” [inside.java]>> Kotlin协程和反馈流简介 [infoq.com]>> 一个优良的博客: Optic首席执行官Aidan Cunniffe介绍OpenAPI、合同测试等等 [spring.io]降级的工夫到了: >> Spring Framework 5.3 来到 GA版本 [spring.io]>> Spring Framework 5.2.10 和 5.1.19 能够应用了! [spring.io]>> Spring Tools 4.8.1 released版本公布 [spring.io]>> Spring Data Neumann SR5, Moore SR11, and Lovelace SR21 可用! [spring.io]2. 技术>> Bulldozer: 批量数据从数据仓库转移到在线键值存储 [netflixtechblog.com] ...

November 2, 2020 · 1 min · jiezi

关于spring:八整合spring-cloud云服务架构-commonserviceeureka-项目构建过程

咱们针对于HongHu cloud的eureka我的项目做以下构建,整个构建的过程很简略,我会将每一步都构建过程记录下来,心愿能够帮忙到大家: 创立一个名为particle-common-eureka的maven我的项目,继承particle-commonservice,具体的pom.xml配置文件如下:1. <?xml version="1.0" encoding="UTF-8"?> 2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4. <modelVersion>4.0.0</modelVersion> 6. <parent> 7. <groupId>com.ml.honghu</groupId> 8. <artifactId>particle-commonservice</artifactId> 9. <version>0.0.1-SNAPSHOT</version> 10. </parent> 12. <artifactId>particle-commonservice-eureka</artifactId> 13. <packaging>jar</packaging> 15. <name>particle-commonservice-eureka</name> 16. <description>particle-commonservice project for Spring Boot</description> 18. <dependencies> 19. <dependency> 20. <groupId>org.springframework.cloud</groupId> 21. <artifactId>spring-cloud-starter-eureka-server</artifactId> 22. </dependency> 23. <dependency> 24. <groupId>org.springframework.boot</groupId> 25. <artifactId>spring-boot-starter-security</artifactId> 26. </dependency> 27. <dependency> 28. <groupId>org.springframework.boot</groupId> 29. <artifactId>spring-boot-devtools</artifactId> 30. </dependency> 32. <dependency> 33. <groupId>org.springframework.boot</groupId> 34. <artifactId>spring-boot-starter-test</artifactId> 35. <scope>test</scope> 36. </dependency> 38. </dependencies> 40. <build> 41. <plugins> 42. <plugin> 43. <groupId>org.springframework.boot</groupId> 44. <artifactId>spring-boot-maven-plugin</artifactId> 45. <executions> 46. <execution> 47. <id>1</id> 48. <goals> 49. <goal>repackage</goal> 50. </goals> 51. </execution> 52. <execution> 53. <id>2</id> 54. <goals> 55. <goal>build-info</goal> 56. </goals> 57. </execution> 58. </executions> 59. <configuration> 60. <executable>true</executable> 61. </configuration> 63. </plugin> 64. </plugins> 65. </build> 66. </project>在启动类入口援用eureka的相干配置,代码如下:1. package com.ml.honghu; 3. import org.springframework.boot.SpringApplication; 4. import org.springframework.boot.autoconfigure.SpringBootApplication; 5. import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 7. @EnableEurekaServer 8. @SpringBootApplication 9. public class ServiceApplication { 11. public static void main(String[] args) { 12. SpringApplication.run(ServiceApplication.class, args); 13. } 14. }配置application.yml文件1. # server (eureka 默认端口为:8761) 2. server: 3. port: 8761 5. # spring 6. spring: 7. application: 8. name: particle-commonservice-erueka 10. # eureka 11. eureka: 12. client: 13. # 是否注册到eureka 14. register-with-eureka: true 15. # 是否从eureka获取注册信息 16. fetch-registry: false 17. availability-zones: 18. honghu: honghuZone 19. service-url: 20. honghuZone: http://honghu:123456@localhost:8761/eureka/ 21. defaultZone: http://honghu:123456@localhost:8761/eureka/ 22. instance: 23. prefer-ip-address: true 24. hostname: localhost 25. metadataMap: 26. zone: honghuZone 27. user: ${security.user.name} 28. password: {security.user.password} 30. # 指定环境 31. environment: dev 32. #指定数据中心 33. datacenter: honghu 34. # 敞开自我保护模式 35. server: 36. enable-self-preservation: false 37. #设置清理有效节点的工夫距离,默认60000,即是60s 38. eviction-interval-timer-in-ms: 60000 40. # 服务认证 41. security: 42. basic: 43. enabled: true 44. user: 45. name: honghu 46. password: 123456 48. management: 49. security: 50. enabled: false减少我的项目的log机制和打包运行机制(前面咱们会具体编写针对于Linux Centos下的打包部署机制)(企业架构源码能够加求球:叁五三陆二肆柒二伍玖)自此整个我的项目部署实现,通过手动形式进行Run As --> Spring Boot App,运行后果如下:控制台运行后果: ...

November 2, 2020 · 2 min · jiezi

关于spring:深入分析Spring-与-Spring-MVC容器

1 Spring MVC WEB配置Spring Framework自身没有Web性能,Spring MVC应用WebApplicationContext类扩大ApplicationContext,使得领有web性能。那么,Spring MVC是如何在web环境中创立IoC容器呢?web环境中的IoC容器的构造又是什么构造呢?web环境中,Spring IoC容器是怎么启动呢? 以Tomcat为例,在Web容器中应用Spirng MVC,必须进行四项的配置: 批改web.xml,增加servlet定义;编写servletname-servlet.xml(servletname是在web.xm中配置DispactherServlet时使servlet-name的值)配置;contextConfigLocation初始化参数、配置ContextLoaderListerner;Web.xml配置如下: <!-- servlet定义:前端处理器,承受的HTTP申请和转发申请的类 --> <servlet> <servlet-name>court</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <!-- court-servlet.xml:定义WebAppliactionContext上下文中的bean --> <param-name>contextConfigLocation</param-name> <param-value>classpath*:court-servlet.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>court</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 配置contextConfigLocation初始化参数:指定Spring IoC容器须要读取的定义了非web层的Bean(DAO/Service)的XML文件门路 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/court-service.xml</param-value> </context-param> <!-- 配置ContextLoaderListerner:Spring MVC在Web容器中的启动类,负责Spring IoC容器在Web上下文中的初始化 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>复制代码如果感觉看完文章有所播种的话,能够关注我一下哦知乎:秃顶之路 b站:linux亦有归途 每天都会更新咱们的公开课录播以及编程干货和大厂面经或者间接点击链接c/c++ linux服务器开发高级架构师来课堂上跟咱们讲师面对面交换须要大厂面经跟学习纲要的小伙伴能够加群973961276获取 在web.xml配置文件中,有两个次要的配置:ContextLoaderListener和DispatcherServlet。同样的对于spring配置文件的相干配置也有两局部:context-param和DispatcherServlet中的init-param。那么,这两局部的配置有什么区别呢?它们都负责什么样的职责呢? 在Spring MVC中,Spring Context是以父子的继承构造存在的。Web环境中存在一个ROOT Context,这个Context是整个利用的根上下文,是其余context的双亲Context。同时Spring MVC也对应的持有一个独立的Context,它是ROOT Context的子上下文。 对于这样的Context构造在Spring MVC中是如何实现的呢?上面就先从ROOT Context动手,ROOT Context是在ContextLoaderListener中配置的,ContextLoaderListener读取context-param中的contextConfigLocation指定的配置文件,创立ROOT Context。 Spring MVC启动过程大抵分为两个过程: ContextLoaderListener初始化,实例化IoC容器,并将此容器实例注册到ServletContext中;DispatcherServlet初始化;2 Web容器中Spring根上下文的加载与初始化Web容器调用contextInitialized办法初始化ContextLoaderListener,在此办法中,ContextLoaderListener通过调用继承自ContextLoader的initWebApplicationContext办法实例化Spring Ioc容器。 ...

November 1, 2020 · 3 min · jiezi

关于spring:Spring-Boot-整合连接池

Spring Boot 整合连接池在理论开发中应用程序与数据库交互时,“取得连贯”或在“开释资源”是十分耗费资源的两个过程,为了解决如此类性能问题,通常这种状况咱们采纳连接池技术重用连贯Connection对象,如图1所示。图-1其实Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商须要让本人的连接池实现这个接口。而后咱们的应用程序中耦合这个接口,便能够不便的切换不同厂商的连接池,常见的连接池有DBCP、C3P0、DRUID、HikariCP等。 通过连接池获取连贯的一个根本过程,如图2所示:图-2 在图-2中,用户先通过DataSource对象的getConnection()办法,获取一个连贯,如果池中有连贯,则间接将连贯返回给用户。如果池中没有连贯,则会调用Dirver(驱动)对象的connect办法从数据库获取,拿到连贯后,能够将连贯在连接池中也放一份,而后再将连贯返回给调用用户。 一、整合HikariCP连接池HikariCP号称是目前世界上最快的连接池,有江湖一哥的名称,目前在SpringBoot工程默认举荐应用HikariCP连接池。咱们在创立一个新我的项目时步骤如下: 第一步:增加依赖。 编辑我的项目中的pom.xml,查找MySQL Driver、JDBC API 依赖,依赖增加后,会在pom.xml文件中主动增加如下两个依赖配置: 1.mysql数据库驱动依赖。 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope></dependency>2.spring对象jdbc反对(此时会默认帮咱们下载HiKariCP连接池) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId></dependency>第二步:配置连接池。 关上application.properties配置文件,增加如下内容。 spring.datasource.url=jdbc:mysql:///dbgoods?serverTimezone=GMT%2B8&characterEncoding=utf8spring.datasource.username=rootspring.datasource.password=root第三步:进行单元测试。 package com.cy.pj.common.datasource;import java.sql.SQLException;import javax.sql.DataSource;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;@SpringBootTestpublic class DataSourceTests {@Autowired private DataSource dataSource; @Test public void testConnection() throws Exception{ System.out.println(dataSource.getConnection()); }}第四步:原理剖析,如图-3所示。 图-3 在图-3中,演示了咱们在测试类DataSourceTests中基于DataSource获取连贯的一个根本过程。 二、Spring Boot整合MyBatis框架MyBatis是一个优良的长久层框架,底层基于JDBC实现与数据库的交互。并在JDBC操作的根底上做了封装的优化,他借助灵便的SQL定制,参数以及后果集的映射形式,更好的适应了以后互联网技术的倒退。MyBatis框架的简略利用框架,如图-4所示:图-4 在以后互联网利用我的项目中,MyBatis框架通常会由spring框架进行资源整合,作为技术层实现数据交互操作。 1、初始配置增加mybatis启动依赖参考mybatis官网,找到springboot菜单选项。基于菜单项找到MyBatis启动依赖。 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency>留神: 在增加此依赖时,肯定指定其版本(version),因为在springboot默认配置中没有设置mybatis框架版本。 2、MyBatis繁难配置咱们增加了mybatis依赖后,spring框架启动时会对mybatis进行主动配置。例如SqlSessionFactory工厂对象的创立。想要对mybatis进行繁难配置是在application.properties文件中进行: mybatis.configuration.default-statement-timeout=30mybatis.configuration.map-underscore-to-camel-case=true配置mybatis中的sql日志的输入: logging.level.com.cy=DEBUG3、业务剖析根本业务的实现及单元测试 基于Spring对MyBatis框架的整合,实现对商品库中数据的删除操作。 第一步:业务API架构的设计,如图-5所示 图-5 第二步:基于id执行商品删除信息,业务时序见图-6 图-6 业务进阶剖析及实现 在MyBatis框架中定义SQL映射的形式有两种:一种是将SQL映射定义在咱们的xml映射文件中,一种是借助注解将其申明在接口办法上。咱们在理论我的项目中对于简略的SQL映射能够间接以注解的形式进行申明即可,简单SQL还是要写到xml中,充分利用动静SQL进行设计会更好些。 三、Spring Boot整合SpringMVC利用概述 ...

October 31, 2020 · 1 min · jiezi

关于spring:长文Spring学习笔记七Mybatis映射器动态SQL

1 概述本文次要讲述了如何应用MyBatis中的映射器以及动静SQL的配置。 2 MyBatis配置文件概览MyBatis配置文件次要属性如下: <settings>:相干设置,键值对模式<typeAliases>:类型别名<typeHandlers>:类型处理器<objectFactory>:对象工厂<plugins>:插件,蕴含若干个<plugin><environments>:环境配置,蕴含若干个<environment>,在<environment>中能够指定事务管理器<transactionManager>以及数据源<dataSource><databaseIdProvider>:数据库厂商标识<mappers>:映射器,蕴含若干个<mapper>留神程序不能颠倒,否则启动时会产生异样。 3 筹备步骤因为本文大部分的代码都只给出了要害的语句而没有残缺的工程,因而如果想要实现一遍请clone此处的代码(Kotlin请clone此处),并: 利用resources/sql下的脚本文件创建数据库以及数据表,并插入相应数据批改MyBatis、Spring、dhcp2等依赖为最新版本并批改MySQL驱动为对应版本批改applicationContext.xml文件中的数据库用户名,明码以及数据库URL,可能须要批改驱动开启数据库服务并进行测试,运行MainTest中的测试方法即可,失常来说会呈现如下后果: 4 映射器概述MyBatis的映射器由一个接口加上XML映射文件组成,是最简单的组件,映射文件罕用元素如下: <select>:查问语句<insert>/<update>/<delete>:插入/更新/删除语句,返回操作所影响的行数,比方插入了两行,操作胜利了影响的行数则为两行,返回整数2<sql>:自定义的SQL<resultMap>:提供映射规定上面先来看一下最罕用的<select>。 4.1 <select>示例(在mapper/UserDao.xml间接增加即可): <select id="selectById" parameterType="Integer" resultType="pers.init.entity.User"> select * from user where id = #{id}</select>其中id是惟一标识符,承受一个Integer,返回com.pojo.User对象,后果集主动映射到com.pojo.User中。 罕用属性如下: id:<select>语句的全局惟一标识符paramterType:示意传入SQL语句的参数类型的全限定名或别名,可选,能主动推断resultType:执行SQL后返回的类型resultMap:与resultType相似,resultType默认一一对应映射,比方表字段名为id,则映射到实体类的id中,而resultMap须要手动定义映射关系,这样就能够把表字段中的id映射到实体类的id1,或id2,或id3,resultType与resultMap两者须要指定一个,不能同时存在flushCache:设置调用SQL后是否要求MyBatis清空之前查问的本地缓存以及二级缓存,默认falseuseCache:启动二级缓存,默认truetimeout:超时参数,单位秒fetchSize:获取记录的总条数设定statementType:应用哪个JDBC的Statement,取值能够为STATEMENT/PREPARED/CALLABLE,别离示意Statement/PreparedStatement/CallableStatementresultSetType:针对JDBC的ResultSet,可设置为FORWARD_ONLY/SCROLL_SENSITIVE/SCROLL_INSENSITIVE,别离示意只容许向前拜访/双向滚动,不及时更新/双向滚动,及时更新并批改UserDao,增加一个selectById办法: User selectById(Integer id);能够间接测试了: @Testpublic void selectById(){ System.out.println(dao.selectById(1));}上面来看一下如何传递多个参数。 4.2 传递参数有了最根本的select后,传递id这种繁多参数很容易,然而理论状况中很多时候须要传递多个参数,MyBatis中传递多个参数有两种形式: 通过Map传递通过JavaBean传递4.2.1 Map能够应用Map传递多个参数,示例<select>如下: <select id="selectByMap" resultType="pers.init.entity.User" parameterType="map"> select * from user where name like concat('%', #{name}, '%') and age = #{age}</select>参数名name以及age是Map的键。 接着在UserDao下增加: User selectByMap(Map<String,String> map);而后在主类中应用Map增加键值对: @Testpublic void selectByMap(){ Map<String,String> map = new HashMap<>(); map.put("name","111"); map.put("age","33"); System.out.println(dao.selectByMap(map));}这样就能传递多个参数进行查问了。 4.1.2 应用JavaBean传递多个参数的另一种办法是利用JavaBean传递,创立一个POJO类: ...

October 30, 2020 · 7 min · jiezi

关于spring:一起来读官方文档SpringIOC10

1.11。应用JSR 330规范注解从Spring 3.0开始,Spring提供了对JSR-330规范注解(依赖注入)的反对。 这些注解的扫描形式与Spring注解雷同。 要应用它们,您须要在类门路中蕴含相干的jar。 如果你应用Maven, javax。 注入工件在规范Maven存储库中可用(https://repo1.maven.org/maven2/javax/inject/javax.inject/1/)。 你能够增加以下依赖到你的文件pom.xml:<dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version></dependency>1.11.1。@Inject和@Named除了@Autowired,您能够应用@javax.inject.Inject注入: import javax.inject.Inject;public class SimpleMovieLister { private MovieFinder movieFinder; @Inject public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } public void listMovies() { this.movieFinder.findMovies(...); // ... }}与@Autowired一样,你能够在字段级、办法级和结构参数级应用@Inject。 此外,您能够将注入点申明为提供者,从而容许按需拜访作用域较短的bean,或者通过Provider.get()提早调用拜访其余bean。 以下示例提供了先前示例的变体: import javax.inject.Inject;import javax.inject.Provider;public class SimpleMovieLister { private Provider<MovieFinder> movieFinder; @Inject public void setMovieFinder(Provider<MovieFinder> movieFinder) { this.movieFinder = movieFinder; } public void listMovies() { this.movieFinder.get().findMovies(...); // ... }}如果要为应该注入的依赖项应用qualified名称,则应应用@Named批注,如以下示例所示: ...

October 30, 2020 · 7 min · jiezi

关于spring:六整合spring-cloud云服务架构-企业云架构commonservice代码结构分析

以后的散布式微服务云架构平台应用Maven构建,所以common-service的通用服务依照maven构建独立的零碎服务,构造如下: particle-commonservice: spring cloud 零碎服务根我的项目,所有服务项目的根依赖。 particle-commonservice-admin: spring cloud/boot的微服务治理、监控平台(外面会集成很多的组件服务项目)(企业架构源码能够加求球:叁五三陆二肆柒二伍玖) particle-commonservice-apigateway:API网关通用服务项目,所有的申请首先会通过这个网关。有点相似于前端控制器模式,也有点相似于 Facade模式。因为所有的申请会先通过这个 api 网关,所以能够在这里做权限管制,平安,负载平衡,申请散发,监控等等。以下的一张图片是从网上找的,不便大家了解: particle-commonservice-cache:针对于分布式缓存提供服务化我的项目,封装分布式缓存redis等。 particle-commonservice-config: 提供独立的微服务配置管理我的项目我的项目。配置管理工具包,让你能够把配置放到近程服务器,集中化治理集群配置,目前反对本地存储、Git以及Subversion。 particle-commonservice-erueka: 提供独立的微服务服务发现、注册治理平台。云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。 particle-commonservice-mq: 提供独立的消息中间件服务平台。包含对风行的阿里rocketmq、rabbit mq、kafka分布式消息中间件的服务治理(这里集成了多种计划,供使用者抉择)。 particle-commonservice-sso: 提供对立用户登录、认证单点登录平台。应用第三方OAuth2.0的解决方案,通过组织在资源拥有者和HTTP服务商之间的被批准的交互动作代表用户,容许第三方利用代表用户取得拜访的权限。同时为Web利用,桌面利用和手机提供对立认证登录服务。 particle-commonservice-turbine:是聚合服务器发送事件流数据的一个工具,用来监控集群下hystrix的metrics状况,提供独立的服务项目。 particle-commonservice-zipkin:提供独立的服务项目,为SpringCloud利用实现了一种分布式追踪解决方案。分布式跟踪零碎数据流次要分为三个步骤:采集、发送和落盘剖析,Zipkin官网给出的设计图,不便大家了解: 从当初开始,我这边会将近期研发的spring cloud微服务云架构的搭建过程和精华记录下来,帮忙更多有趣味研发spring cloud框架的敌人,大家来一起探讨spring cloud架构的搭建过程及如何使用于企业我的项目。

October 30, 2020 · 1 min · jiezi

关于spring:Spring学习笔记菜鸟必看带你吃透Spring

Spring介绍Spring 是一个开源框架,是一个分层的 JavaEE 一站式框架。 所谓一站式框架是指 Spring 有 JavaEE 开发的每一层解决方案。 WEB层:SpringMVCService层:Spring的Bean治理,申明式事务DAO层:Spring的JDBC模板,ORM模板长处: IOC:不便解耦合AOP:对程序进行扩大轻量级框架不便与其余框架整合Spring应用 Spring开发包解压后的目录介绍: docs: Spring 开发标准和APIlibs: Spring jar 包和源代码schema: Spring 配置文件的约DataAccess 用于数据拜访,WEB 用于页面显示,外围容器也就是IOC局部。 管制反转(IOC) 管制反转(Inversion of Control)是指将对象的创立权反转(交给)Spring。 应用IOC就须要导入IOC相干的包,也就是上图中外围容器中的几个包:beans,context,core,expression四个包。 实现原理 传统形式创建对象: UserDAO userDAO=new UserDAO(); 进一步面向接口编程,能够多态: UserDAO userDAO=new UserDAOImpl(); 这种形式的毛病是接口和实现类高耦合,切换底层实现类时,须要批改源代码。程序设计应该满足OCP元祖,在尽量不批改程序源代码的根底上对程序进行扩大。此时,能够应用工厂模式: class BeanFactory{ public static UserDAO getUserDAO(){ return new UserDAOImpl(); } } 此种形式尽管在接口和实现类之间没有耦合,然而接口和工厂之间存在耦合。 应用工厂+反射+配置文件的形式,实现解耦,这也是 Spring 框架 IOC 的底层实现。 //xml配置文件 //<bean id="userDAO" class="xxx.UserDAOImpl"></bean> class BeanFactory{ public static Object getBean(String id){ //解析XML //反射 Class clazz=Class.forName(); ...

October 29, 2020 · 7 min · jiezi

关于spring:IDEA插件精选安利一个IDEA骚操作一键生成方法的序列图

在平时的学习/工作中,咱们会常常面临如下场景: 浏览他人的代码浏览框架源码浏览本人很久之前写的代码。千万不要感觉工作就是单纯写代码,理论工作中,你会发现你的大部分工夫理论都花在了浏览和了解已有代码上。 为了可能更快更清晰地搞清对象之间的调用关系,我常常须要用到序列图。手动画序列图还是很麻烦费时间的,不过 IDEA 提供了一个叫做SequenceDiagram 的插件帮忙咱们解决这个问题。通过 SequenceDiagram 这个插件,咱们一键能够生成时序图。 何为序列图?网上对于序列图的定义有很多,我感觉都不太好了解,太形象了。最神奇的是,大部分文章对于序列图的定义居然都是截然不同,看来大家是充分发挥了写代码的“精华”啊! 我还是简略说一说我的了解吧!不过,说实话,我本人对于 Sequence Diagram 也不是很清朗。上面的形容如有问题和须要欠缺的中央,还请指出。 序列图(Sequence Diagram),亦称为循序图,是一种UML行为图。示意零碎执行某个办法/操作(如登录操作)时,对象之间的顺序调用关系。这个顺序调用关系能够这样了解:你须要执行零碎中某个对象 a 提供的办法/操作 login(登录),然而这个对象又依赖了对象 b 提供的办法 getUser(获取用户)。因而,这里就有了 a -> b 调用关系之说。 再举两个例子来说一下! 下图是微信领取的业务流程时序图。这个图形容了微信领取相干角色(顾客,商家...)在微信领取场景下,根底领取和领取的的顺序调用关系。 下图是我写的一个 HTTP 框架中的执行某个办法的序列图。这个图形容了咱们在调用 InterceptorFactory类的 loadInterceptors() 办法的时候,所波及到的类之间的调用关系。 另外,国内个别更喜爱称说序列图为"时序图"。 如果你依照纯翻译的角度来说, sequence 这个单词并无"工夫"的意思,只有序列,程序等意思,因而也有人说“时序图”的说法是不精确的。如果从定义角度来说,时序图这个形容是没问题的。因为 Sequence Diagram 中每条音讯的触发机会的确是依照工夫程序执行的。我感觉称说 Sequence Diagram 为时序图或者序列图都是没问题的,不必太纠结。 哪些场景下须要查看类的时序图?咱们在很多场景下都须要时序图,比如说: 浏览源码 :浏览源码的时候,你可能须要查看调用指标办法波及的相干类的调用关系。特地是在代码的调用层级比拟多的时候,对于咱们了解源码十分有用。(_题外话:理论工作中,大部分工夫理论咱们都花在了浏览了解已有代码上。_)技术文档编写 :咱们在写我的项目介绍文档的时候,为了让他人更容易了解你的代码,你须要依据外围办法为相干的类生成时序图来展现他们之间的调用关系。梳理业务流程 :当咱们的零碎业务流程比较复杂的时候,咱们能够通过序列图将零碎中波及的重要的角色和对象的之间关系可视化进去。......如何应用 IDEA 依据类中办法生成时序图?通过 SequenceDiagram 这个插件,咱们一键能够生成时序图。 并且,你还能够: 点击时序图中的类/办法即可跳转到对应的中央。从时序图中删除对应的类或者办法。将生成的时序图导出为 PNG 图片格式。装置咱们间接在 IDEA 的插件市场即可找到这个插件。我这里曾经装置好了。 如果你因为网络问题没方法应用 IDEA 自带的插件市场的话,也能够通过IDEA 插件市场的官网手动下载安装。 简略应用选中办法名(留神不要选类名),而后点击鼠标右键,抉择 Sequence Diagram 选项即可! ...

October 26, 2020 · 1 min · jiezi

关于spring:跨站资源共享CORS原理深度解析

我置信如果你写过前后端拆散的web应用程序,或者写过一些ajax申请调用,你可能会遇到过CORS谬误。 CORS是什么?它与安全性无关吗?为什么要有CORS?它解决了什么目标?CORS是怎么运行的?如果您有这些问题,那么这篇文章非常适合您。 一、什么是CORS?要理解什么是CORS(Cross-Origin Resource Sharing:跨站资源共享),首先咱们须要理解什么是同源策略Same Origin Policy(SOP)。SOP是所有的古代浏览器都具备的安全措施,它不容许从一个加载的js脚本和资源的Origin域与另一个Origin域进行交互。换句话说,如果您的网站是www.example.com,则您无奈向www.test.com收回XHR申请。 那么SOP有什么用?如果没有同源策略的限度,你想想会产生什么? 比方:您曾经登录到微博,并且不小心关上了一个歹意网站。该网站能够向微博发出请求,并从您微博登录的会话中提取个人信息。这显然是微小的平安问题,为了避免这种状况,在浏览器中施行同源策略的限度。实际上,服务器并没有意识到在浏览器端产生的这所有,您依然能够应用curl或postman收回雷同的申请,并且所有响应失常,因为这些工具上没有SOP。 如果说SOP是限度跨源拜访的一种形式,那么CORS是一种绕过SOP限度并容许您的前端向服务器提出非法申请的办法。 如果您的服务端确实是存在跨域的状况(实际上对于古代分布式应用,这很常见),因为SOP限度您的客户端将无奈向多节点跨域服务器收回xhr申请。救星就呈现了,CORS使咱们可能以平安且可治理的形式做到跨域申请,冲破同源策略的限度。 二、同源策略的源(Same Origin Policy的Origin)源由三局部组成:协定,hostip(域)和端口。例如 http://example.com/xxx/index.html和http://example.com/yyy/index.html是同源,http://example.com:80和http://example.com(对于http默认端口为80)是同源。因为协定不同,http://example.com/app1和https://example.com/app2是不同的源。http://example.com,http://www.example.com因为域名不同,也是不同的源十分要留神的是http://localhost 和http://127.0.0.1是不同的源同源策略就是:不容许不同的ip、端口、协定的利用在浏览器内进行相互资源共享、申请调用。 三、CORS如何运作?CORS标准容许服务器向浏览器返回一些HTTP Headers,浏览器能够基于这些HTTP Headers来决定是否冲破SOP的限度。最次要的一个HTTP Headers是Access-Control-Allow-Origin。 //指标服务容许所有的网站对其进行跨域拜访Access-Control-Allow-Origin: * //指标服务容许特定的网站对其进行跨域拜访Access-Control-Allow-Origin: https://example.comCORS有两种类型的申请:“simple”简略申请和“preflight”预检申请,依据申请办法的不同由浏览器确定应用哪种申请。 simple简略申请:如果合乎以下所有条件,则API申请被视为简略申请: API办法是以下办法之一:GET,POST或HEAD。Content-Type申请头蕴含:application/x-www-form-urlencoded,multipart/form-data,text/plain这两个条件将形成大多数简略申请的用例,然而能够在此处找到更具体的简略申请条件列表。 如果您的API申请被视为simple简略申请,这个申请就能够间接被发送给服务器。服务器应用CORS HTTP Headers进行响应,浏览器将查看Access-Control-Allow-Origin后决定这个申请是否能够冲破同源策略的限度,进行下一步的解决。 preflight预检申请:如果您的API申请不满足成为简略申请的规范(最常见不满足简略申请规范的Content-Type值为application/json),则浏览器将在发送理论申请之前收回预检申请。 举一个例子,咱们尝试应用GET申请https://example.com/status,Content-Type是application/json,所以浏览器认为它不合乎一个简略申请的规范,因而浏览器会在收回理论申请之前收回预检申请,这个预检申请是应用HTTP的 OPTIONS办法收回的: curl --location --request OPTIONS 'http://example.com/status' \--header 'Access-Control-Request-Method: GET' \--header 'Access-Control-Request-Headers: Content-Type, Accept' \--header 'Origin: http://test.com'下面的curl就是模仿预检申请,理论作用是:浏览器心愿通知服务器,我的理论申请将应用HTTP GETmethod进行调用,Content-Type与Accept作为HTTP headers,这个申请是从https://test.com发动的。服务器响应此申请: HTTP/1.1 204 No ContentAccess-Control-Allow-Origin: *Access-Control-Allow-Methods: OPTIONS, GET, HEAD, POSTAccess-Control-Allow-Headers: Content-Type, AcceptAccess-Control-Allow-Origin:容许发出请求的源,或者*能够从任何起源发出请求。(即容许跨域的源)Access-Control-Allow-Methods:容许的以逗号分隔的HTTP办法列表。(即容许跨域的HTTP办法)Access-Control-Allow-Headers:容许发送的HTTP headers列表。浏览器收到服务端的预检申请响应之后,在咱们的示例中服务器响应*能够从任何起源发出请求,因而当初浏览器将再次拜访https://example.com/status,应用GET办法(不再是OPTIONS办法),浏览器将不再限度该申请的收回与响应数据的接管。如果预检申请响应的Origin是特定的Access-Control-Allow-Origin: http://domain.com,浏览器将呈现Cross-Origin Request Blocked谬误。因为服务器端预检后果只容许http://domain.com收回跨域申请,不容许其余利用向我收回跨域申请。 四、如何解决CORS谬误咱们当初晓得什么是CORS及其工作原理,前面的事件其实就简略了。从下面的内容咱们须要留神的是,对CORS的齐全控制权在服务器,即服务器能够容许或禁止源的跨域拜访。所以说跨域问题的解决个别都在服务端进行,不同的服务端的解决HTTP 申请头的代码是不一样的,当然也能够不必写代码,比方:nginx、haproxy设置。然而万变不离其宗:最终都是对HTTP Headers进行重写。 ...

October 26, 2020 · 1 min · jiezi

关于spring:Spring

待欠缺

October 25, 2020 · 1 min · jiezi

关于spring:Spring

待欠缺

October 25, 2020 · 1 min · jiezi

关于spring:Spring为什么要使用三级缓存解决循环依赖问题

咱们都晓得Spring为了解决循环依赖应用了三级缓存 Spring三级缓存一级缓存singletonObjects用于保留BeanName和创立bean实例之间的关系,beanName -> bean instance private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);二级缓存earlySingletonObjects保留提前曝光的单例bean对象 private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);三级缓存singletonFactories保留beanName和创立bean实例之间的关系,与singletonObjects不同的中央在于,当一个单例bean被放到这外面后,bean在创立过程中,能够通过getBean办法获取到,目标是用来检测循环援用 private final Map<String, Object> singletonFactories = new HashMap(16);在创立bean的时候,首先从缓存中获取单例的bean,这个缓存就是singletonObjects,如果获取不到且bean正在创立中,就再从earlySingletonObjects中获取,如果还是获取不到且容许从singletonFactories中通过getObject拿到对象,就从singletonFactories中获取,如果获取到了就存入earlySingletonObjects并从singletonFactories中移除。 为什么要应用三级缓存?一级缓存首先咱们看看一级缓存行不行,如果只留第一级缓存,那么单例的Bean都存在singletonObjects 中,Spring循环依赖次要基于Java援用传递,当获取到对象时,对象的field或者属性能够延后设置,实践上能够,然而如果延后设置出了问题,就会导致残缺的Bean和不残缺的Bean都在一级缓存中,这个援用时就有空指针的可能,所以一级缓存不行,至多要有singletonObjects 和earlySingletonObjects 两级。 两级缓存那么咱们再看看两级缓存行不行 当初有A的field或者setter依赖B的实例对象,同时B的field或者setter依赖了A的实例,A首先开始创立,并将本人裸露到 earlySingletonObjects 中,开始填充属性,此时发现自己依赖B的属性,尝试去get(B),发现B还没有被创立,所以开始创立B,在进行属性填充时初始化A,就从earlySingletonObjects 中获取到了实例化但没有任何属性的A,B拿到A后实现了初始化阶段,将本人放到singletonObjects中,此时返回A,A拿到B的对象持续实现初始化,实现后将本人放到singletonObjects中,由A与B中所示意的A的属性地址是一样的,所以A的属性填充完后,B也获取了A的属性,这样就解决了循环的问题。仿佛完满解决,如果就这么应用的话也没什么问题,然而再加上AOP状况就不同了,被AOP加强的Bean会在初始化后代理成为一个新的对象,也就是说: 如果有AOP,A依赖于B,B依赖于A,A实例化实现裸露进来,开始注入属性,发现援用B,B开始实例化,应用A裸露的对象,初始化实现后封装成代理对象,A再将代理后的B注入,再做代理,那么代理A中的B就是代理后的B,然而代理后的B中的A是没用代理的A。显然这是不对的,所以在Spring中存在第三级缓存,在创建对象时判断是否是单例,容许循环依赖,正在创立中,就将其从earlySingletonObjects中移除掉,并在singletonFactories放入新的对象,这样后续再查问beanName时会走到singletonFactory.getObject(),其中就会去调用各个beanPostProcessor的getEarlyBeanReference办法,返回的对象就是代理后的对象。 public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } /** * Add the given singleton factory for building the specified singleton * if necessary. * <p>To be called for eager registration of singletons, e.g. to be able to * resolve circular references. * @param beanName the name of the bean * @param singletonFactory the factory for the singleton object */ protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { this.singletonFactories.put(beanName, singletonFactory); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } }

October 24, 2020 · 1 min · jiezi

关于spring:Spring框架学习

Spring的长处Spring是一个开源收费的框架Spring是一个轻量级,非入侵式的框架管制反转(IOC),面向切面编程(AOP)反对事务处理,对框架整合反对 Spring就是一个轻量级的管制反转(IOC),面向切面编程(AOP)的框架 IOC实质管制反转IOC(Inversion of Control),是一种设计思维,DI(依赖注入)是实现IOC的一种办法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中,咱们应用面向对象编程,对象的创立与对象间的依赖关系齐全硬编码在程序中,对象的创立由程序本人管制,管制反转后将对象的创立转移给第三方,集体认为所谓管制反转就是︰取得依赖对象的形式反转了。采纳XML形式配置Bean的时候,Bean的定义信息是和实现拆散的,而采纳注解的形式能够把两者合为一体,Bean的定义信息间接以注解的模式定义在实现类中,从而达到了零配置的目标。管制反转是一种通过形容(XML或注解)并通过第三方去生产或获取特定对象的形式。在Spring中实现管制反转的是loC容器,其实现办法是依赖注入(Dependency Injection,Dl)。 依赖注入结构其注入set注入bean的主动拆卸ByNameByType应用注解代理模式AOP申明式事务事务要么都胜利,要么都失败确保完整性和一致性事务在我的项目开发中非常重要,波及数据的一致性事务ACID准则 原子性一致性隔离性持久性XML配置事务<! --配置申明式事务--><property name="dataSource" ref="dataSource"/>/bean><! --联合AOP实现事务的织入--><! --配置再务告诉--><tx:advice id="txAdvice" transaction-manager="transactionManager"><!--给哪那些办法配置事务--><!--配置事务的播个性: propagation= --><tx:attributes><tx:method name="add" propagation="REQUIRED"/><tx:method name="delete" propagation="REQUIRED"/><tx:method name="update" propagation="REQUIRED"/><tx:method name="query" read-only="true"/><tx:method name="*"propagation="REQUIRED"/></tx:attributes></tx:advice><!--配置事务切入--><!-- com.cy.mapper.*.*(..) 示意mapper包下所有类里的所有办法--><aop:config><aop:pointcut id="txPointCut" expression="execution(* com.cy.mapper.*.*(..))"><aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/></aop:config>

October 24, 2020 · 1 min · jiezi

关于spring:Spring框架

什么是Spring?Spring是一个轻量级开源框架,以IoC(管制反转)和AOP(面向切面编程)为外围。Spring的实质是管理软件中的对象,即创建对象和保护对象之间的关系。 Spring的劣势1).不便解耦,简化开发 通过 Spring提供的 IoC容器,能够将对象间的依赖关系交由Spring进行管制,防止硬编码所造成的适度程序耦合。用户也不用再为较为底层的需要编写代码,能够更专一于下层的利用。 2).AOP 编程的反对 通过 Spring的 AOP 性能,不便进行面向切面的编程,许多不容易用传统OOP(Object Oriented Programming:面向对象编程) 实现的性能能够通过 AOP 轻松应酬。 3).申明式事务的反对 能够将咱们从枯燥烦闷的事务管理代码中解脱进去,通过申明式形式灵便的进行事务的治理,进步开发效率和品质。 4).不便程序的测试 能够用非容器依赖的编程形式进行简直所有的测试工作,测试不再是低廉的操作,而是顺手可做的事件。 5).不便集成各种优良框架 Spring能够升高各种框架的应用难度,提供了对各种优良框架(Struts、Hibernate、Hessian、Quartz等)的间接反对。 6).升高 JavaEE API 的应用难度。 Spring对 JavaEE API(如 JDBC、JavaMail、近程调用等)进行了薄薄的封装层,使这些API 的应用难度大为升高。 7).Spring框架源码是经典学习范例 Spring的源代码设计精妙、构造清晰、匠心独用,处处体现着巨匠对Java设计模式灵活运用以及对 Java技术的浅近造诣。它的源代码无疑是Java技术的最佳实际的范例。 什么是程序的耦合耦合性(Coupling),也叫耦合度,是对模块间关联水平的度量。耦合的强弱取决于模块间接口的复杂性、调用模块的形式以及通过界面传送数据的多少。模块间的耦合度是指模块之间的依赖关系,包含控制关系、调用关系、数据传递关系。模块间分割越多,其耦合性越强,同时表明其独立性越差(升高耦合性,能够进步其独立性)。耦合性存在于各个领域,而非软件设计中独有的,然而咱们只探讨软件工程中的耦合。 总结:在软件工程中,耦合指的就是指对象之间的依赖关系。对象之间的依赖水平越高,耦合度就越高。对象之间的耦合越高,保护老本越高。因而对象的设计应使类和构件之间的耦合最小。 升高程序之间的依赖水平,即升高程序之间的耦合度的过程就叫做解耦。 SpringIOC管制反转IOC(Inverse Of Control)管制反转,即,把创建对象的权力交给框架。也就是指将对象的创立、对象的存储、对象的治理交给了spring容器。 Spring DI依赖注入DI(Dependency Injection)依赖注入 。 依赖注入,即组件之间的依赖关系由容器在利用零碎运行期来决定,也就是由容器动静地将某种依赖关系的指标对象实例注入到利用零碎中的各个关联的组件之中。

October 23, 2020 · 1 min · jiezi

关于spring:Spring-527和SpringBoot-233中文翻译发布啦

这段时间因为工作上的起因以及正在和其余技术平台在单干推出一些本人的货色所以有一点点耽误没有定时能在公众号推送相干技术分享,请各位小伙伴释怀我这边正快马加鞭的整顿中哟。目前的进度曾经根本实现Spring5外围的翻译以及SpringBoot的翻译。这里把SpringBoot的翻译提前是因为有不少小伙伴须要这个材料。依据我在博客中公布的翻译Spring系列打算能够看出翻译的工作量是十分微小的所以请各位小伙伴稍安勿躁,然而这个打算我会始终执行上来。那么通过一段时间的翻译和整顿现阶段曾经翻译实现了Spring、SpringBoot。So !!! Spring系列分为: 《SpringFramework-5.2.7中文解析-外围篇》《SpringFramework-5.2.7中文解析-测试篇》《SpringFramework-5.2.7中文解析-数据存储篇》《SpringFramework-5.2.7中文解析-Servlet篇》《SpringFramework-5.2.7中文解析-Reactive篇》SpringBoot分为: 《SpringBoot 2.3.3中文解析》现公布相干电子版,有一些中央可能没有修改到位的中央请小伙伴多多谅解和提出你贵重的意见。感激小伙伴的关注!请大家多多分享我的公众号给其余小伙伴,去帮忙更多的小伙伴。 留神:该电子书文档禁止所有的商业性质应用和售卖,版权归作者所有。 作者集体从事金融行业,就任过易极付、思建科技、某网约车平台等重庆一流技术团队,目前就任于某银行负责对立领取零碎建设。本身对金融行业有强烈的喜好。同时也实际大数据、数据存储、自动化集成和部署、散布式微服务、响应式编程、人工智能等畛域。同时也热衷于技术分享创建公众号和博客站点对常识体系进行分享。关注公众号:青年IT男 获取最新技术文章推送!博客地址: http://youngitman.tech CSDN: https://blog.csdn.net/liyong1... 微信公众号: 技术交换群: 该系列文章请关注微信公众:青年IT男

October 23, 2020 · 1 min · jiezi

关于spring:手撸了一个HTTP框架支持Sprng-MVCIOCAOP拦截器配置文件读取

https://github.com/Snailclimb/jsoncat :仿 Spring Boot 但不同于 Spring Boot 的一个轻量级的 HTTP 框架间隔上一次给小伙伴们汇报简易版的“Spring Boot”的实现状况曾经有半个月了。工夫过得是真特么快啊! 01这半个月里,我的 HTTP 框架曾经反对 AOP、拦截器(也是 AOP 的一种)、属性文件读取等性能了。 ???? 目前的话,整个 HTTP 框架根本曾经具备我最后想要实现的全副性能了。也算是兑现了诺言,虎头蛇尾了。 性能具体的实现状况如下: <img src="https://img-blog.csdnimg.cn/20201021201230434.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0MzM3Mjcy,size_16,color_FFFFFF,t_70#pic_center" style="zoom:50%;" /> 很多读者小伙伴可能感觉我写的比拟容易。不过, 说实话,我两头写的过程中也遇到了很多问题。为了解决写这个框架遇到的一些问题,我熬了很多夜,也早起了很屡次。 我不算是奋青。个别状况下,我平时都是早晨 9 点半之后玩几把王者光荣,到了 12 点左右就睡觉了。晚上的话,我个别都是 8 点左右起床。简直日日如此。 然而,写这个 HTTP 框架的时候,我记得有 3 次我熬夜到凌晨 2 点左右。有 2 个晚上,因为有“灵感”,我 5 点多久爬起来写代码了。 说这些,不是为了博同情让大家感觉我写的多辛苦,也不是体现我有多致力。 这些都是很平时的经验罢了!我感觉大部分程序员都经验过: 夜深人静的时候,忽然本人写的代码出了点问题,不解决就不想睡觉。某个晚上,忽然惊醒,灵感爆棚,关上电脑开始写代码。不过,我是真的不举荐大家熬夜!那我本人来说,每次熬夜就会导致我第二天甚至是第三天精神不振,重大影响效率。这还只是熬夜的短期影响,长期作息不衰弱的话,必定对身材的残害特地大。 情理都懂,不过,大部分都像我一样,还是会偶然熬夜。 02整个框架的目录构造如下: 框架实现局部依照不同的功能模块进行组织,比拟直观。提供了残缺的框架应用示例,并且还为其编写了测试。<img src="https://img-blog.csdnimg.cn/20201022084612423.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0MzM3Mjcy,size_16,color_FFFFFF,t_70#pic_center" style="zoom:50%;" /> 03开源的魅力在于他人能够对你的我的项目进行反馈,并且,遇到对你的我的项目感兴趣的敌人,他们还会帮你一起欠缺和开发我的项目。 拿 jsoncat 来说。jsoncat 开源之后,一位叫做“hellohello-tom”的老哥便参加了进来帮忙开发。 tom 哥代码写的很不错,帮忙 jsoncat 实现了很多性能!真的十分十分非常感谢!爱你哦!老哥! 我俩因为这个我的项目常常在微信上交换,或者这就是编程的魅力吧!哈哈哈! 我平时少在微信聊天的,然而因为这个开源我的项目和老哥聊了挺多的。 轻易截了两张图: 我感觉一个我的项目开发是比拟禁忌只有本人一个人的。每个人都会有思维局限,你很难发现你的代码须要某些改良的中央以及存在的问题。 ...

October 23, 2020 · 1 min · jiezi

关于spring:Spring框架的环境搭建和测试

Spring简介1.什么是Springspring是分层的JavaSE及JavaEE利用于全栈的轻量级开源框架,以IoC(Inverse Of Control:管制反转/反转管制)和AOP(Aspact Oriented Programming:面向切面编程)为外围,提供了体现层SpringMVC和长久层Spring JDBC以及业务层事务管理等泛滥模块的企业级利用技术,还能整合开源世界中泛滥驰名的第三方框架和类库,逐步成为应用最多的JavaEE企业应用开源框架。 2.Spring的劣势Spring 无处不在Spring 是易扩大的,不便集成各种优良框架Spring 不便解耦,易于开发(简化开发)Spring 速度快Spring 是平安的Spring 社区很宏大,备受反对Spring框架源码是经典学习范例环境的搭建1 创立Maven我的项目创立好后我的项目工程报错,那是因为短少web.xml文件。所以须要生成web.xml文件。 2 我的项目工程的目录构造 3 增加pom.xml文件(引入junit、spring的jar包)<dependencies> <!-- 增加junit的jar包 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <!-- 增加spring的jar包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.3.RELEASE</version> </dependency></dependencies> 4 在applicationContext.xml中增加文件头信息:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>5 创立UserDao接口在UserDao接口中增加一个办法 package com.yanan.dao;/** * 测试接口 * @author 慕客 * */public interface UserDao { public void add();}6 创立UserDaoImpl实现类该实现类实现了UserDao接口 package com.yanan.dao.impl;import com.yanan.dao.UserDao;/** * 该实现类实现了UserDao接口 * @author 慕客 * */public class UserDaoImpl implements UserDao{ @Override public void add() { System.out.println("UserDaoImpl.add办法执行了......"); }}7配置applicationContext.xml文件将UserDao接口的实现类的实例交给Spring容器创立,在外围配置文件中增加如下内容: ...

October 22, 2020 · 1 min · jiezi

关于spring:SpringAop中jdk和CGlib代理

一,Aop 概述1. Aop 是什么?AOP(Aspect Orient Programming)是一种设计思维,是软件设计畛域中的面向切面编程,它是面向对象编程(OOP)的一种补充和欠缺。它以通过预编译形式和运行期动静代理形式,实现在不批改源代码的状况下给程序动静对立增加额定性能的一种技术 2. Aop相干术语剖析切面(aspect): 横切面对象,个别为一个具体类对象(能够借助@Aspect申明)2.告诉(Advice):在切面的某个特定连接点上执行的动作(扩大性能),例如@around,@before,@after等。3.连接点(joinpoint):程序执行过程中某个特定的点,个别指被拦挡到的的办法。4.切入点(pointcut):对多个连接点(Joinpoint)一种定义,个别能够了解为多个连接点的汇合。 3.Aop疾速实际 3.1 阐明:3.1.1:增加Aop启动依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency>3.1.2:注解阐明1.@Aspect 注解用于标识或者形容AOP中的切面类型,基于切面类型构建的对象用于为指标对象进行性能扩大或控制目标对象的执行。2.@Pointcut注解用于形容切面中的办法,并定义切面中的切入点(基于特定表达式的形式进行形容),在本案例中切入点表达式用的是bean表达式,这个表达式以bean结尾,bean括号中的内容为一个spring治理的某个bean对象的名字。3.@Around注解用于形容切面中办法,这样的办法会被认为是一个盘绕告诉(外围业务办法执行之前和之后要执行的一个动作),@Aournd注解外部value属性的值为一个切入点表达式或者是切入点表达式的一个援用(这个援用为一个@PointCut注解形容的办法的办法名)。4.ProceedingJoinPoint类为一个连接点类型,此类型的对象用于封装要执行的指标办法相干的一些信息。只能用于@Around注解形容的办法参数。4.Aop实操演练(注:idea ,spring我的项目)

October 22, 2020 · 1 min · jiezi

关于spring:提交商品订单-SysResult

SysResult个别后端业务解决实现之后,须要给客户端返回无效信息,告知客户端程序执行是否正确 @Data@Accessors(chain = true)@NoArgsConstructor@AllArgsConstructorpublic class SysResult { private Integer status; private String msp;//服务器提示信息 胜利 失败 private Object data;//服务器返回值数据 //利用static的静态方法 将数据动静返回 public static SysResult fail(){ return new SysResult(201,"业务执行失败",null); } public static SysResult success(){ return new SysResult(200,"业务执行胜利",null); } public static SysResult success(Object data){ return new SysResult(200,"业务执行胜利",data); } public static SysResult success(String msp,Object data){ return new SysResult(200,msp,data); }}订单pojo import java.util.Date;import java.util.List;import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.TableId;import com.baomidou.mybatisplus.annotation.TableName;import lombok.Data;import lombok.experimental.Accessors;@TableName("tb_order")@Data@Accessors(chain=true)public class Order extends BasePojo{ @TableField(exist=false) //入库操作疏忽该字段 private OrderShipping orderShipping; //封装订单商品信息 一对多 @TableField(exist=false) //入库操作疏忽该字段 private List<OrderItem> orderItems; @TableId private String orderId; private String payment; private Integer paymentType; private String postFee; private Integer status; private Date paymentTime; private Date consignTime; private Date endTime; private Date closeTime; private String shippingName; private String shippingCode; private Long userId; private String buyerMessage; private String buyerNick; private Integer buyerRate;}订单商品pojo ...

October 22, 2020 · 2 min · jiezi

关于spring:掌握这些springboot的配置方式让你工作效率翻个倍

springboot的多种配置形式java配置次要靠java类和一些注解,比拟罕用的注解有:@Configuration :申明一个类作为配置类,代替xml文件@Bean :申明在办法上,将办法的返回值退出Bean容器,代替 标签@Value :根本类型或String属性注入@PropertySource :指定内部属性文件前面以Druid连接池配置为例,数据库名称为springboot_test形式一<!--pom.xml --><dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.6</version> </dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope></dependency># src/resources/jdbc.propertiesjdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://127.0.0.1:3306/bosjdbc.username=rootjdbc.password=123456//src\main\java\com\itheima\config\DruidConfig.java@Configuration@PropertySource("classpath:jdbc.properties")public class DruidConfig { @Value("${jdbc.url}") String url; @Value("${jdbc.driverClassName}") String driverClassName; @Value("${jdbc.username}") String username; @Value("${jdbc.password}") String password; @Bean public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driverClassName); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; }}解读: @Configuration :申明咱们 DruidConfig是一个配置类@PropertySource :指定属性文件的门路是: classpath:jdbc.properties@Value 为属性注入值(只能是根本类型或String)@Bean将 dataSource() 办法申明为一个注册Bean的办法,Spring会主动调用该办法,将办法的返回值退出Spring容器中。形式二<!--pom.xml --><dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.6</version></dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope></dependency><!-- ============不增加在IDEA 会报红,但并不影响性能 ================= --><dependency> <groupId> org.springframework.boot </groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional></dependency><!--============================================================== --># src/resources/application.propertiesjdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://127.0.0.1:3306/bosjdbc.username=rootjdbc.password=123456//src\main\java\com\itheima\config\DruidConfig.java@ConfigurationProperties(prefix = "jdbc")public class DruidProperties { private String url; private String driverClassName; private String username; private String password; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getDriverClassName() { return driverClassName; } public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}//src\main\java\com\itheima\config\DruidConfig.java@Configuration@EnableConfigurationProperties(DruidProperties.class)public class DruidConfig { @Bean public DataSource dataSource(DruidProperties dp) { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(dp.getDriverClassName()); dataSource.setUrl(dp.getUrl()); dataSource.setUsername(dp.getUsername()); dataSource.setPassword(dp.getPassword()); return dataSource; }}解读: ...

October 22, 2020 · 2 min · jiezi

关于spring:Java9系列第8篇Module模块化编程

我打算在后续的一段时间内,写一系列对于java 9的文章,尽管java 9 不像Java 8或者Java 11那样的外围java版本,然而还是有很多的个性值得关注。期待您能关注我,我将把java 9 写成一系列的文章,大略十篇左右,本文是第8篇。 java9系列文章拜访地址在Java 9版本中Java 语言引入了一个十分重要的概念:模块(module)。如果对javascript代码模块化治理比拟相熟的小伙伴,看到Java 9的模块化治理,应该有似曾相识的感觉。 一、什么是Java module?与Java 中的package有些相似,module引入了Java代码分组的另一个级别。每个这样的分组(module)都蕴含许多子package包。通过在一个模块的源代码文件package的根部,增加文件module-info.java来申明该文件夹及其子文件夹为一个模块。该文件语法如下: module xxx.yyy{ .... }其中xxx.yyy是模块module申明的名称,不是package名称。 二、模块导出package文件module-info.java能够指定该模块上面的哪些package对外可见、可拜访。通过一个新的关键字exports来实现该性能。 module xxx.yyy{ exports com.zimug.java9; }com.zimug.java9代表一个package。 须要留神的是:即便给定package包中的类是public的,如果未通过'exports'显式导出其程序包,则它们在模块内部也是不可见的(在编译时和运行时都是如此)。三、模块导入package如果另一个模块想要应用被导出的package包中的类,能够用requires关键字在其module-info.java文件中来导入(读取)指标模块的package包。 module def.stu{ requires xxx.yyy;}四、Java module的意义在笔者看来,Java 9引入module 模块化管理系统,更多的是从安全性的角度思考。Java 代码中90%以上的破绽都是由反射和拜访权限管制粒度有余引起的,Java 9的模块化零碎正好能解决这个问题。Java 9 module提供另一个级别的Java 代码可见性、可拜访性的管制。 比如说:咱们都晓得当一个class被润饰为private的时候,意味着这个类是外部类。对于顶级类(外部类)来说,只有两种修饰符:public和默认(default)。这也就意味着一个问题,有些public class咱们原本是打算在jar包定义的范畴内应用的,然而后果却是任何引入了这个jar的我的项目都能够应用这个jar外面所有的public class代码。 也就是咱们的原意是在无限范畴内提供公开拜访,后果却是无限度的对外公开。在引入Java 9模块化之后,能够实现无限范畴内的代码public拜访权限,将代码公开辨别为:模块内部无限范畴的公开拜访和模块外部的公开拜访。 五、实例在此示例中,我将创立两个模块“ common.widget”和“ data.widget”,并将它们搁置在单个文件夹“ modules-examples/src”下。文件“ module-info.java”将搁置在每个模块的根文件夹下。文件及目录格局如下: D:\modules-example>tree /F /A\---src +---common.widget | | module-info.java | | | +---com | | \---zimug | | RendererSupport.java | | | \---org | \---jwidgets | SimpleRenderer.java | \---data.widget | module-info.java | \---com \---example Component.java第一个模块本代码文件目录:modules-example/src/common.widget/org/jwidgets/SimpleRenderer.java。这个package在后文中没有被exports。 ...

October 22, 2020 · 1 min · jiezi

关于spring:推荐4款个人珍藏的IDEA插件帮你写出不那么差的代码

@[toc] 目前的话,我(Guide哥)是在 Github 开源了两个轮子,一个繁难的 RPC 框架,一个轻量级的 HTTP 框架。代码构造清晰,实现优雅(这个自夸就很不要脸),感兴趣的小伙伴能够看一下。 在写代码的时候,有几个 IDEA 插件对于我标准代码以及更高效地实现编码工作有奇效。 那明天就简略聊聊我平时写代码过程中,有哪些 IDEA 插件对我帮忙最大吧! Codota:代码智能提醒我始终在用的一个插件,能够说十分好用了(我身边的很多大佬平时写代码也会用这个插件)。 Codota 这个插件用于智能代码补全,它基于数百万Java程序,可能依据程序上下文提醒补全代码。相比于IDEA自带的智能提醒来说,Codota 的提醒更加全面一些。 如果你感觉 IDEA 插件装置的太多比拟卡顿的话,不必放心!Codota 插件还有一个对应的在线网站(https://www.codota.com/code),在这个网站上你能够依据代码关键字搜寻相干代码示例,十分不错! 我在工作中常常会用到,说实话的确给我带来了很大便当,比方咱们搜寻 Files.readAllLines相干的代码,搜寻进去的后果如下图所示: 另外,Codota 插件的根底性能都是收费的。你的代码也不会被泄露,这点你不必放心。 简略来看看 Codota 插件的骚操作吧! 代码智能补全咱们应用HttpUrlConnection 建设一个网络连接是真的样的: 咱们创立线程池当初变成上面这样: 下面只是为了演示这个插件的弱小,实际上创立线程池不举荐应用这种形式, 举荐应用 ThreadPoolExecutor 构造函数创立线程池。我上面要介绍的一个阿里巴巴的插件-Alibaba Java Code Guidelines 就检测进去了这个问题,所以,Executors上面用波浪线标记了进去。 代码智能搜寻除了,在写代码的时候智能提醒之外。你还能够间接选中代码而后搜寻相干代码示例。 Alibaba Java Code Guidelines:阿里巴巴 Java 代码标准阿里巴巴 Java 代码标准,对应的Github地址为:https://github.com/alibaba/p3c 。十分举荐装置! 装置实现之后倡议将与语言替换成中文,提醒更加敌对一点。 依据官网形容: 目前这个插件实现了开发手册中的的53条规定,大部分基于PMD实现,其中有4条规定基于IDEA实现,并且基于IDEA Inspection实现了实时检测性能。局部规定实现了Quick Fix性能,对于能够提供Quick Fix但没有提供的,咱们会尽快实现,也欢送有趣味的同学退出进来一起致力。 目前插件检测有两种模式:实时检测、手动触发。上述提到的开发手册也就是在Java开发畛域赫赫有名的《阿里巴巴Java开发手册》。 手动配置检测规定你还能够手动配置相干 inspection规定: ...

October 21, 2020 · 1 min · jiezi

关于spring:SpringBoot项目中各模块顺序化理解试

我的项目构造服务端客户端映射文件 依据零碎调用程序,理论开发会由后端向前端开发客户端向服务端发动申请 $(()=>{//jquery中提供的页面加载实现当前要执行的函数 doLoadUI("load-user-id","user/user_list") doLoadUI("load-dept-id","dept/dept_list") doLoadUI("load-role-id","role/role_list") doLoadUI("load-menu-id","menu/doMenuUI") doLoadUI("load-log-id","log/doLogUI");})点击分页查问 进行初始化模块页面user_list.html $(document).ready(function(){ $("#pageId").load("doPageUI",function(){ doGetObjects(); }); $(".input-group-btn") .on("click",".btn-search",doQueryObjects) .on("click",".btn-add,.btn-update",doLoadEditUI); $("tbody").on("click",".btn-valid",doValidById);});doLoadEditUI办法判断所点击的事件 function doLoadEditUI(){ //1.断定点击的对象 var title; if($(this).hasClass("btn-add")){ title="增加用户"; doLoadPage(title); }else if($(this).hasClass("btn-update")){ title="批改用户"; var id=doGetCheckedId(); console.log("id="+id) if(!id){ alert("请先抉择"); return; } //基于id进行查问并加载编辑页面 doFindObjectById(id,title); }}触发“增加用户” 按钮事件 function doLoadPage(title){ var url="user/user_edit" $("#mainContentId").load(url,function(){ $(".box-title").html(title); }) }获取url为user/user_edit user_edit.html 初始化页面和事件注册 $(document).ready(function(){ //页面加载实现当前加载角色信息并初始化页面 doLoadRoles(); //事件注册 $(".box-footer") .on("click",".btn-cancel",doCancel) .on("click",".btn-save",doSaveOrUpdate); $("#treeLayer") .on("click",".btn-cancel",doHideTree) .on("click",".btn-confirm",doConfirm); $(".form-horizontal") .on("click",".load-sys-dept",doLoadZTreeNodes);});点击“增加”按钮 触发doSaveOrUpdate办法 function doSaveOrUpdate(){ var rowData=$("#mainContentId").data("rowData"); //1.获取表单数据 var params=doGetEditFormData(); if(rowData)params.id=rowData.user.id; //2.发动异步申请 var insertUrl="user/doSaveObject"; var updateUrl="user/doUpdateObject"; var url=rowData?updateUrl:insertUrl; console.log(params); $.post(url,params,function(result){ if(result.state==1){ alert(result.message); doCancel(); }else{ alert(result.message); } })} ...

October 21, 2020 · 1 min · jiezi

关于spring:SpringMVC详解1怎么接收请求

在学习springmvc怎么接管申请前,咱们须要先讲一讲servlet。它其实java提供的一个Web组件。而咱们比拟熟知的Tomcat容器就是一种Servlet容器的实现,顾名思义就是用来治理servlet的。 最早学习java的时候我置信每个人都学习过Servlet的常识,咱们只须要继承一个HttpServlet,而后在WEB-INF目录下的web.xml文件中配置Servlet的拜访对外门路,最初启动Tomcat服务器。咱们就能够在浏览器中拜访该Servlet了。 不过在springboot中提供了更简略的实现,代码如下: @WebServlet(urlPatterns = "/self_servlet/*")public class MvcTest extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("I received a req:"+req.getMethod()+"-"+req.getServletPath()+"-"+req.getRequestURI()); }}最初只须要将该类注册到容器当中去就能够了。当然注册Servlet,Springboot提供了两种形式:1.应用@WebServlet注解,再通过@ServletComponentScan 扫描该类,会主动注册。2.@Bean的形式也提供注册办法: @Bean public ServletRegistrationBean<MvcTest> registrationInit(){ ServletRegistrationBean<MvcTest> registrationBean =new ServletRegistrationBean<>(); registrationBean.addUrlMappings("/self_servlet/*"); registrationBean.setServlet(new MvcTest()); return registrationBean; }最初咱们申请测试一下http://localhost:8080/self_servlet/dsadsd,控制台中就会打印出相应的信息。 I received a req:GET-/self_servlet-/self_servlet/dsadsd以上的学习咱们就晓得了,只有向spring注册一个ServletBean就能够拦挡到申请,而后再办法内做解决。没错!springboot也是这么做的!这里咱们简略的引出此类,后续详解。 这个类就是DispatcherServlet,它就是HttpServlet的一个子类。容器会调用service办法,最终调用DispatcherServlet#doService的办法,代码如下: @Override protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { // …… 疏忽代码,只保留次要逻辑 try { doDispatch(request, response); } // …… }能够看到的是MVC的控制器再接管到申请后会调用doDispatch办法进行一个散发操作。咱们很容易想到在这个办法里会进行最终的办法调用和后果返回。具体实现留在前面文章。 ...

October 21, 2020 · 1 min · jiezi

关于spring:使用SpringBoot发送Gmail和QQ邮箱

应用SpringBoot发送Gmail和QQ邮箱 概述如何应用SpringBoot发送Gmail、QQ邮箱,发送文本、附件和模板。 代码如下:DemoApplication.java `package com.example.sendmail.demo;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.GetMapping;@SpringBootApplicationpublic class DemoApplication {    public static void main(String[] args) {        SpringApplication.run(DemoApplication.class, args);    }    @Controller    class MainController{        @Value("${spring.mail.username}")        private String username;        /**         * 发送邮件页面         * @return         */        @GetMapping(value = {"/","/send/form"})        public String form(Model model){            model.addAttribute("from",username);            return "send-form";        }    }}` MailController.java `package com.example.sendmail.demo;import lombok.RequiredArgsConstructor;import lombok.extern.log4j.Log4j2;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import javax.mail.MessagingException;@Log4j2@RestController@RequiredArgsConstructor@RequestMapping("/send")public class MailController {    private final MailService mailService;    /**     * 发送文本     * @param mailBody     * @return     */    @PostMapping("/text")    public Boolean text(@RequestBody MailBody mailBody){        return mailService.sendText(mailBody);    }    /**     * 发送附件     * @param mailBody     * @param file     * @return     * @throws MessagingException     */    @PostMapping("/attach")    public Boolean attach(@RequestParam("mailBody") MailBody mailBody,@RequestParam("file") MultipartFile file) throws MessagingException {        mailBody.setFile(file);        log.info("file name:{}",file.getOriginalFilename());        log.info("mailBody:{},",mailBody.toString());        return mailService.sendAttachment(mailBody);    }    /**     * 发送模板     * @param mailBody     * @return     * @throws MessagingException     */    @PostMapping("/template")    public boolean template(@RequestBody MailBody mailBody) throws MessagingException {        return mailService.sendTemplate(mailBody);    }}`

October 21, 2020 · 1 min · jiezi

关于spring:第三波面试题依旧免费领

金九银十的九十月思否编程为大家精心筹备了大厂面试题第一波面试题为阿里P7第二波面试题为腾讯第三波面试题为头条第四波临时窃密哈每一次只有500份每一次都是抢领一空这一次是行将到来的第三波祝你查漏补缺,欠缺知识点顺利get到大厂offer啦 本期面试题-头条同样只有500这一期还是免费送助你圆大厂梦也助你盘点本人的知识库 面试交换群对于面试那些事儿不定期的岗位举荐外部福利等你一起来见证 第四波也是最初一波面试题已在路上,敬请期待 流动工夫2020 年10 月 20 日 ↓2020 年10 月 25 日 流动规定关注公众号,即刻支付仅限500份 更多精彩内容请增加HR小姐姐

October 20, 2020 · 1 min · jiezi

关于spring:纯干货分享2020阿里java岗笔试面试题总结附答案

前言2020金九银十马上完结,现为大家整顿了这次金九银十面试阿里的面试题总结,都是我从敌人那拿到的面试真题,话不多说,满满的干货分享给大家! int a=10是原子操作吗?是的。 留神点: i++(或++i)是非原子操作,i++是一个多步操作,而且是能够被中断的。i++能够被宰割成3步,第一步读取i的值,第二步计算i+1;第三部将最终值赋值给i。 * int a = b;不是原子操作。从语法的级别来看,这是也是一条语句,是原子的;然而从理论执行的二进制指令来看,因为古代计算机CPU架构体系的限度,数据不能够间接从内存搬运到另外一块内存,必须借助寄存器中断,这条语句个别对应两条计算机指令,行将变量b的值搬运到某个寄存器(如eax)中,再从该寄存器搬运到变量a的内存地址: mov eax, dword ptr [b] mov dword ptr [a], eax 既然是两条指令,那么多个线程在执行这两条指令时,某个线程可能会在第一条指令执行结束后被剥夺CPU工夫片,切换到另外一个线程而产生不确定的状况。 innodb反对全文索引吗?5.6版本之后InnoDB存储引擎开始反对全文索引,5.7版本之后通过应用ngram插件开始反对中文。之前仅反对英文,因为是通过空格作为分词的分隔符,对于中文来说是不适合的。MySQL容许在char、varchar、text类型上建设全文索引。 innodb反对表锁吗?反对,补充:一般的增删改 是表锁,退出索引的增删改是行锁,执行查问时不加任何锁的。 HTTP短连贯怎么变成长连贯。在header中退出 --Connection:keep-alive。 调用yeild()会阻塞吗? 阻塞指的是暂停一个线程的执行以期待某个条件产生(如某资源就绪)。yield() 办法:yield() 使得线程放弃以后分得的 CPU 工夫,然而不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 工夫。调用 yield() 的成果等价于调度程序认为该线程已执行了足够的工夫从而转到另一个线程。yield()只是使以后线程从新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。sleep()可使优先级低的线程失去执行的机会,当然也能够让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。 虚拟机栈是线程共享的吗? 不是。  JVM初始运行的时候都会调配好 Method Area(办法区) 和Heap(堆) ,而JVM 每遇到一个线程,就为其调配一个 Program Counter Register(程序计数器) , VM Stack(虚拟机栈)和Native Method Stack (本地办法栈), 当线程终止时,三者(虚拟机栈,本地办法栈和程序计数器)所占用的内存空间也会被开释掉。这也是为什么我把内存区域分为线程共享和非线程共享的起因,非线程共享的那三个区域的生命周期与所属线程雷同,而线程共享的区域与JAVA程序运行的生命周期雷同,所以这也是零碎垃圾回收的场合只产生在线程共享的区域(实际上对大部分虚拟机来说只产生在Heap上)的起因。 栈区:每个线程蕴含一个栈区,栈中只保留根底数据类型的值(比方int i=1中1就是根底类型的对象)和对象的援用以及根底数据的援用每个栈中的数据(根底数据类型和对象援用)都是公有的,其余栈不能拜访。栈分为3个局部:根本类型变量区、执行环境上下文、操作指令区(寄存操作指令)。堆区:存储的全副是对象,每个对象都蕴含一个与之对应的class的信息。(class的目标是失去操作指令)jvm只有一个堆区(heap)被所有线程共享,堆中不寄存根本类型和对象援用,只寄存对象自身 。办法区:又叫动态区,跟堆一样,被所有的线程共享。办法区蕴含所有的class和static变量。办法区中蕴含的都是在整个程序中永远惟一的元素,如class,static变量。(两者区别为堆区寄存new进去的对象信息,办法区寄存自身就具备的类信息)常量寄存在JVM的那个区域?办法区: 又叫动态区,跟堆一样,被所有的线程共享。它用于存储曾经被虚拟机加载的类信息、常量、动态变量、即时编译器编译后的代码等数据。 window.postMessage() 办法能够平安地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具备雷同的协定(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain设置为雷同的值) 时,这两个脚本能力互相通信。window.postMessage() 办法提供了一种受控机制来躲避此限度,只有正确的应用,这种办法就很平安。 所有的对象都调配到堆中吗?      答:不肯定。 CopyOnWriteArrayList是线程平安的吗? 答:是的。 CopyOnWriteArrayList应用了一种叫写时复制的办法,当有新元素增加到CopyOnWriteArrayList时,先从原有的数组中拷贝一份进去,而后在新的数组做写操作,写完之后,再将原来的数组援用指向到新数组。创立新数组,并往新数组中退出一个新元素,这个时候,array这个援用依然是指向原数组的。当元素在新数组增加胜利后,将array这个援用指向新数组。      CopyOnWriteArrayList的整个add操作都是在锁的爱护下进行的。这样做是为了防止在多线程并发add的时候,复制出多个正本进去,把数据搞乱了,导致最终的数组数据不是咱们冀望的。 public boolean add(E e) { //1、先加锁 final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; //2、拷贝数组 Object[] newElements = Arrays.copyOf(elements, len + 1); //3、将元素退出到新数组中 newElements[len] = e; //4、将array援用指向到新数组 setArray(newElements); return true; } finally { //5、解锁 lock.unlock(); } }因为所有的写操作都是在新数组进行的,这个时候如果有线程并发的写,则通过锁来管制,如果有线程并发的读,则分几种状况: ...

October 20, 2020 · 3 min · jiezi

关于spring:redis-管理工具

我的项目作用: 嵌入式治理redis键值.我的项目基于 SpringBoot 进行开发. 次要依赖: spring-boot-starter-data-redis 2.3.3.RELEASE 版本进行开发.我的项目地址: https://github.com/huifer/vie...引入依赖<dependency> <groupId>com.github.huifer</groupId> <artifactId>view-redis-servlet</artifactId> <version>1.0-SNAPSHOT</version></dependency>配置账号密码view: redis: login_name: admin password: admin启动类增加@EnableViewRedisServlet启动后拜访 ip:port/redis 进入登录页 登陆后能够查看,redis 根本信息 key 相干操作 具体操作请各位在应用中进行操作. 上面截图几个性能图.key 查问 新建key 批改 key name zset 编辑

October 20, 2020 · 1 min · jiezi

关于spring:Java9系列第7篇JavautilOptional优化与增强

我打算在后续的一段时间内,写一系列对于java 9的文章,尽管java 9 不像Java 8或者Java 11那样的外围java版本,然而还是有很多的个性值得关注。期待您能关注我,我将把java 9 写成一系列的文章,大略十篇左右,本文是第7篇。 java9系列文章拜访地址java.util.Optional是在Java 8版本中新增的类,肯定水平上能够改善编程过程中的NullPointException的问题。在Java 9中对这个类新增了一些办法进行加强,上面咱们一起来看一下,顺便也回顾一下在Java 8中它的用法。 一、Java9的ifPresentOrElse(Consumer,Runnable)1.1.Java 9 中的加强如果存在值,则此新办法将执行给定的Consumer操作,否则运行给定的Runnable操作。上面的代码先应用Java 8的的Stream流过滤3的倍数,而后通过findFirst找到第一个3的倍数。如果找到一个这样的值,就print控制台打印进去;如果没找到一个这样的值,就输入"没有找到3的倍数" ifPresentOrElse(Consumer,Runnable)的语义能够解释为:ifPresent就Consumer,OrElse就Runnable。这是Java 9 才有的加强办法。 IntStream.of(1, 2, 4) .filter(i -> i % 3 == 0) .findFirst() .ifPresentOrElse(System.out::println, () -> { System.out.println("没有找到3的倍数"); });在1、2、4中没有3的倍数,所以输入后果如下 没有找到3的倍数如果是上面的2、6、8数组被过滤,最终控制台输入后果为:6 IntStream.of(2, 6, 8) .filter(i -> i % 3 == 0) .findFirst() .ifPresentOrElse(System.out::println, () -> { System.out.println("没有找到3的倍数"); }); // 61.2.回顾一下Java 8中的写法Java 8 Optional.isPresent():如果应用Java 8 ,没有ifPresentOrElse(Consumer,Runnable)办法,上文中同样的代码你应该是这样写的:本人去写if和else进行判断。同样输入:没有找到3的倍数 OptionalInt opt = IntStream.of(1, 2, 4) .filter(i -> i % 3 == 0) .findFirst(); if (opt.isPresent()) { System.out.println(opt.getAsInt()); } else { System.out.println("没有找到3的倍数"); }Java 8 Optional.ifPresent():ifPresent()办法在值不存在的时候,没有提供一个可选的操作。所以上面的代码在执行之后,没有orElse动作,没有任何输入,这样不是很敌对。 ...

October 20, 2020 · 1 min · jiezi

关于spring:面试JAVA基础之SpringSpringBufferSpringbuilder有那些区别一

SpringSpring类是一个不可变类,对象一旦被创立后,这个对象中的字符序列是不可变的,直到这个对象被销毁。留神:Spring a="111"; a="222";最终a的后果是222。因为再次给a赋值时,并不是对堆中实例对象从新复制,而是生成了一个新的对象,并指向后者的实例对象,之前的对象任然存在,如果没有援用,则会被垃圾回收。 SpringBufferStringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创立当前,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等办法能够扭转这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就能够调用它的toString()办法将其转换为一个String对象。留神:StringBuffer对象是一个字符序列可变的字符串,它没有从新生成一个对象,而且在原来的对象中能够连贯新的字符串。 SpringBuilderStringBuilder类也代表可变字符串对象。实际上,StringBuilder和StringBuffer根本类似,两个类的结构器和办法也基本相同。不同的是:StringBuffer是线程平安的,而StringBuilder则没有实现线程平安性能,所以性能略高。 StringBuffer是如何实现线程平安的呢?StringBuffer类中的办法都增加了synchronized关键字, 也就是给这个办法增加了一个锁,用来保障线程平安。Java9的改良Java9改良了字符串(包含String、StringBuffer、StringBuilder)的实现。在Java9以前字符串采纳char[]数组来保留字符,因而字符串的每个字符占2字节;而Java9的字符串采纳byte[]数组再加一个encoding-flag字段来保留字符,因而字符串的每个字符只占1字节。所以Java9的字符串更加节俭空间,字符串的性能办法也没有受到影响。

October 19, 2020 · 1 min · jiezi

关于spring:SpringBoot-入门案例的实现

业务形容在SpringBoot工程中,疾速实现Bean对象的创立,配置和测试。 API设计剖析在这个入门案例中,以DefaultCache类(一个一般的类)作为设计和利用入口进行剖析和实现,例如: 在上图中形容了DefaultCacheTests类与DefaultCache类的关系,这两个类通过指定注解(@SpringBootTest,@Component)进行了形容,其用意是通知spring框架这个两个类的实例的创立由Spring负责,并且由Spring框架基于@Autowired注解的形容实现DefaultCacheTests实例中无关DefaultCache类型的值的注入(DI)。代码设计及实现第一步:创立一个DefaultCache类,存储到src/main/java目录,而后交给spring治理。 package com.cy.pj.common.cache;@Component public class DefaultCache {}@Component是Spring中用于形容Bean类的一个注解。用于通知Spring这框架个类的实例由Spring创立,当此对象由Spring创立和治理时,默认会将对象存储到池(Bean池)中。第二步:增加sringboot 测试类,进行bean的获取及测试,要放在src/test/java目录中: package com.cy.pj.common.cache;@SpringBootTestpublic class DefaultCacheTests {// is a Object @Autowired private DefaultCache defaultCache;//has a @Test public void testCache() { //use a system System.out.println(defaultCache); }}@SpringBootTest 注解用于通知spring框架,此测试类交给spring治理。@Autowired注解形容属性时,用于通知spring框架要为此属性注入一个值?(至于注入规定,前面课程缓缓增强)运行BUG剖析 总结(Summary)本大节对SpringBoot工程下类的编写,配置和测试做了一个根本实现。重点在如何基于API设计进行代码的实现和测试。

October 19, 2020 · 1 min · jiezi

关于spring:如何理解Spring框架中的Bean对象

Bean对象的定义?在Spring框架中由Spring创立和治理的对象的对象称之为Bean对象。 Bean对象的个性?Spring框架为了更加迷信的治理和利用Bean对象,为其设计相干个性,例如:懒加载、作用域以及生命周期办法。 懒加载(Lazy)在Spring框架中,默认会在启动时会创立所有的Bean对象,但有些bean对象如果长时间不必,启动时就创建对象,会占用其内存资源,从而造成肯定的资源节约,此时咱们能够基于懒加载策略提早对象的创立,在设计类时,在类上增加@Lazy注解,例如: package com.cy.pj.common.pool;@Component@Lazypublic class ObjectPool { public ObjectPool() { System.out.println("ObjectPool()"); }}其中,@Lazy注解中有一个value属性,其默认值为true示意提早加载。作用域(Scope)Spring框架创建对象当前,能够给对象一个作用域,目标是让对象在肯定范畴内能够进行重用,罕用有单例(singleton)和多例(prototype)两种,其中: singleton:此作用域指的是,名字和类型雷同的Bean对象实例在整个Spring容器中只能一份。此实例何时创立与类的提早加载个性配置无关,此实例创立当前,生命周期会由spring框架治理。prototype:此作用域指的是,每次从Spring容器获取对象都会创立新实例,此实例会在须要时创立与lazy个性无关,这个实例创立当前,spring能够对其初始化,但不负责销毁。基于注解@Scope形式设定Bean作用域,代码演示: package com.cy.pj.common.pool;、@Lazy@Scope("singlton")@Componentpublic class ObjectPool { public ObjectPool() { System.out.println("ObjectPool()"); }}Spring中默认bean对象的作用域为singleton,如果心愿是prototype能够应用@Scope("prototype")生命周期办法程序中每个对象都有生命周期,但不是每个对象类型定义时,都要定义生命周期办法,当一个Bean对象创立当前如果还需执行额定初始化,销毁之前也须要额定的其它资源的开释,Spring框架能够为类定义其生命周期办法。如果是注解形式,咱们能够采纳如下两个注解进行实现。 @PostConstruct 注解用于形容bean对象生命周期办法中的初始化办法,此办法会在对象的构造方法之后执行(是对象创立当前的初始化)。@PreDestroy 注解用于形容Bean对象生命周期办法中的销毁办法,此办法会在对象销毁之前执行(当作用域为prototype时,此办法不会执行)。代码演示: package com.cy.pj.common.pool;、@Lazy@Scope("singlton")@Componentpublic class ObjectPool { public ObjectPool() { System.out.println("ObjectPool()"); } @PostConstruct public void init() { System.out.println("init()"); } @PreDestroy public void close() { System.out.println("close()"); }}个别池对象都会设置一些生命周期办法,例如连接池。总结(Summary)本大节次要对Spring框架中的Bean对象个性做了一个概要剖析,能够通过这个剖析理解Spring框架是如何迷信利用bean对象的。

October 19, 2020 · 1 min · jiezi

关于spring:如何理解Spring中的Autowired

@Autowired 简介@Autowired 注解用于形容类中的属性,构造方法,set办法,配置办法等,用于通知Spring框架依照指定规定为属性注入值(DI)。 @Autowired 利用入门基于如下API设计,进行代码实现进而剖析@Autowired利用剖析。 第一步:设计Cache接口 package com.cy.pj.common.cache;public interface Cache { }第二步: 设计Cache接口实现类WeakCache,并交给spring治理。 package com.cy.pj.common.cache; import org.springframework.stereotype.Component; @Component public class WeakCache implements Cache{ }第二步: 设计Cache接口实现类SoftCache,并交给spring治理。 package com.cy.pj.common.cache; @Componentpublic class SoftCache implements Cache{…}第三步:设计单元测试类 package com.cy.pj.common.cache;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest public class CacheTests { @Autowired @Qualifier("softCache") private Cache cache; @Test public void testCache() { System.out.println(cache); }}基于单元测试,剖析@Autowired利用(底层通过反射技术为属性赋值)。 阐明:Spring框架在我的项目运行时如果发现由他治理的Bean对象中有应用@Autowired注解形容的属性,能够依照指定规定为属性赋值(DI)。其根本规定是:首先要检测容器中是否有与属性类型相匹配的对象,如果有并且只有一个则间接注入。其次,如果检测到有多个,还会依照@Autowired形容的属性名查找是否有名字匹配的对象,有则间接注入,没有则抛出异样。最初,如果咱们有明确要求,必须要注入类型为指定类型,名字为指定名字的对象还能够应用@Qualifier注解对其属性或参数进行形容(此注解必须配合@Autowired注解应用)。@Autowired 利用进阶@Autowired 注解在Spring治理的Bean中也能够形容其构造方法,set办法,配置办法等,其规定仍旧是先匹配办法参数类型再匹配参数名,基于如下图的设计进行剖析和实现: 第一步:定义SearchService类并交给Spring治理 package com.cy.pj.common.service;@Componentpublic class SearchService{ private Cache cache; @Autowired public SearchService(@Qualifier("softCache")Cache cache){ this.cache=cache; } public Cache getCache(){ return this.cache; }}@Qualifier能够形容构造方法参数,但不能够形容构造方法。第二步:定义SearchServiceTests单元测试类。 ...

October 19, 2020 · 1 min · jiezi

关于spring:Java9系列第6篇Stream流API的增强

我打算在后续的一段时间内,写一系列对于java 9的文章,尽管java 9 不像Java 8或者Java 11那样的外围java版本,然而还是有很多的个性值得关注。期待您能关注我,我将把java 9 写成一系列的文章,大略十篇左右,本文是第6篇。 java9系列文章拜访地址本文带大家疾速的理解一下在Java 9 种汇合类Colleaction子类都产生了哪些比拟有用的变动与加强。 在Java 9中对Java Util Stream的语法进行了优化和加强,上面我就和大家一起看一下有哪些比拟有价值的应用办法。 1. Stream.takeWhile(Predicate)在进行Stream流的管道数据处理的时候,提供的Predicate条件返回false之后,将跳过残余的数据元素间接返回。在上面的示例中,一旦Predicate条件!"orange" .equals(s)返回false,则将跳过其余元素: String[] fruits = {"apple", "banana", "orange", "mango", "peach"}; Stream<String> stream = Arrays.stream(fruits) .takeWhile(s -> !"orange".equals(s)); stream.forEach(System.out::println);控制台输入后果为,顺次对数组中元素过滤,到orange元素满足了!"orange" .equals(s) === false,流式解决不再持续间接返回。 apple banana须要留神的是:对于无序Stream,如果存在多个与提供的Predicate匹配的元素(多个orange),则此操作返回值是不确定的。 这种办法看上去和Java 8中的Stream.filter()很类似,然而它们的不同之处在于filter()办法只是跳过了不匹配的元素,而后持续进行解决。然而takeWhile()办法在存在匹配项之后会跳过所有残余的元素,有点像continue和break的区别。以下是具备雷同流和Predicate的filter()办法示例: String[] fruits = {"apple", "banana", "orange", "mango", "peach"}; Stream<String> stream = Arrays.stream(fruits).filter(s -> !"orange".equals(s)); stream.forEach(System.out::println);控制台输入如下,只是把orange过滤掉了。 apple banana mango peach2.Stream.dropWhile(Predicate)提供的Predicate条件在管道流中返回false之后,此元素前面的所有数据元素作为返回值返回。 String[] fruits = {"apple", "banana", "orange", "mango", "peach"}; Stream<String> stream = Arrays.stream(fruits) .dropWhile(s -> !"orange".equals(s)); stream.forEach(System.out::println);在下面示例中,一旦Predicate条件!"orange".equals(s) 返回false,管道流中残余的元素将被承受(不被过滤),作为返回值返回: ...

October 19, 2020 · 1 min · jiezi

关于spring:03SpringBoot工程下如何实现对HikariCP连接池的整合转

池化思维剖析池化思维是咱们我的项目开发过程中的一种十分重要的思维,如整数池,字符串池,对象池、连接池、线程池等都是池化思维的一种利用,都是通过复用对象,以缩小因创立和开释对象所带来的资源耗费,进而来晋升零碎性能。例如Integer对象的外部池利用,代码如下: package com.cy.java.pool;public class TestInteger01 { public static void main(String[] args) { Integer n1=100;//Integer.valueOf(100) 编译时优化 Integer n2=100; Integer n3=200; Integer n4=200;//池中没有则new Integer(200) System.out.println(n1==n2);//true System.out.println(n3==n4);//false } }数据库连接池简介背景剖析目开发过程中应用程序与数据库交互时,“取得连贯”或“开释连贯”是十分耗费系统资源的两个过程,频繁地进行数据库连贯的建设和敞开会极大影响零碎的性能,若多线程并发量很大,这样耗时的数据库连贯就可能让零碎变得卡顿。因为TCP连贯的创立开销非常低廉,并且数据库所能承载的TCP并发连接数也有限度,针对这种场景,数据库连接池应运而生。如下图所示: 思考:如果当初是让你去设计一个连接池,你会从什么角度进行设计?第一:物理存储构造(基于什么构造去存储数据)第二:基于什么算法从池中取连贯?第三:基于什么算法从池中移除连贯?第四:当池中没有连贯时,基于什么形式解决连贯申请?第五:池是能够共享,咱们须要思考池在拜访的时并发平安? 连接池原理剖析在零碎初始化的时候,在内存中开拓一片空间,将肯定数量的数据库连贯作为对象存储在对象池里,并对外提供数据库连贯的获取和偿还办法。用户拜访数据库时,并不是建设一个新的连贯,而是从数据库连接池中取出一个已有的闲暇连贯对象;应用结束偿还后的连贯也不会马上敞开,而是由数据库连接池对立治理回收,为下一次借用做好筹备。如果因为高并发申请导致数据库连接池中的连贯被借用结束,其余线程就会期待,直到有连贯被偿还。整个过程中,连贯并不会敞开,而是源源不断地循环应用,有借有还。数据库连接池还能够通过设置其参数来管制连接池中的初始连接数、连贯的上上限数,以及每个连贯的最大应用次数、最大闲暇工夫等,也能够通过其本身的管理机制来监督数据库连贯的数量、应用状况等。 Java中的连接池Java官网,为了在应用程序中更好的利用连接池技术,定义了一套数据源标准,例如javax.sql.DataSource接口,基于这个接口,很多团队或集体创立了不同的连接池对象。而后咱们的应用程序中通过耦合与DataSource接口,便能够不便的切换不同厂商的连接池。Java我的项目中通过连接池获取连贯的一个根本过程,如下图所示: 在上图中,用户通过DataSource对象的getConnection()办法,获取一个连贯。如果池中有连贯,则间接将连贯返回给用户。如果池中没有连贯,则会调用Dirver(驱动,由数据库厂商进行实现)对象的connect办法从数据库获取,拿到连贯当前,能够将连贯在池中放一份,而后将连贯返回给调用方。连贯需求方再次须要连贯时,能够从池中获取,用完当前再还给池对象。 数据库连接池在Java数据库相干中间件产品群中,应该算是底层最根底的一类产品,作为企业应用开发必不可少的组件,有数蠢才们为咱们奉献了一个又一个的优良产品,它们有的随时代倒退,功成身退,有的则还在一直迭代,老而弥坚,更有新生代产品,或性能无敌,或性能全面。目前市场上常见的连接池有DBCP、C3P0,DRUID,HikariCP等。SpringBoot工程下HikariCP整合测试数据初始化关上mysql控制台,而后按如下步骤执行goods.sql文件。第一步:登录mysql。 mysql –uroot –proot第二步:设置控制台编码方式。 set names utf8;第三步:执行goods.sql文件(切记不要关上文件复制到mysql客户端运行)。 source d:/goods.sql其中goods.sql文件内容如下: drop database if exists dbgoods;create database dbgoods default character set utf8;use dbgoods;create table tb_goods( id bigint primary key auto_increment, name varchar(100) not null, remark text, createdTime datetime not null)engine=InnoDB;insert into tb_goods values (null,'java','very good',now());insert into tb_goods values (null,'mysql','RDBMS',now());insert into tb_goods values (null,'Oracle','RDBMS',now());insert into tb_goods values (null,'java','very good',now());insert into tb_goods values (null,'mysql','RDBMS',now());insert into tb_goods values (null,'Oracle','RDBMS',now());insert into tb_goods values (null,'java','very good',now());创立我的项目Module并增加相干依赖第一步:基于IDEA创立我的项目Module,如图所示: ...

October 18, 2020 · 2 min · jiezi

关于spring:java9第5篇Collection集合类的增强与优化

我打算在后续的一段时间内,写一系列对于java 9的文章,尽管java 9 不像Java 8或者Java 11那样的外围java版本,然而还是有很多的个性值得关注。期待您能关注我,我将把java 9 写成一系列的文章,大略十篇左右,本文是第5篇。 java9系列文章拜访地址本文带大家疾速的理解一下在Java 9 种汇合类Colleaction子类都产生了哪些比拟有用的变动与加强。 一、提供Of()办法创立汇合1.1.构建Set汇合对象Java 9 提供了一系列的工厂办法of()来更加简便的构建Set汇合对象。应用of()办法构建java.util.Set咱们就不必一个元素一个元素的add()数据了。但须要留神的是:这种办法构建的Set汇合类对象一旦构建就不能更改,不能再新增汇合元素。 Set<Integer> integers = Set.of(2, 6, 7, 10);System.out.println(integers); //[2, 10, 6, 7]还有许多重载的of()工厂办法供咱们应用 of()//空的set of(E) of(E, E) of(E, E, E) //更多 ...... of(E, E, E, E, E, E, E, E, E, E )// 始终到十个元素 of(E...)//更多参数1.2.构建List汇合对象和Set汇合相似,List汇合类也新增了一系列的of()工厂函数,创立不可变的List汇合对象。 List<Integer> integers = List.of(2, 6, 7, 10); System.out.println(integers); // [2, 6, 7, 10]1.3.构建Map对象尽管Map不是Colleaction的子类,然而咱们个别也把它当作汇合类学习。Map类同样新增了一系列的of()工厂函数,创立不可变的Map对象。惟一的区别是应用Key/Value的模式传递参数。 Map<Integer, String> map = Map.of(2, "two", 6, "six"); System.out.println(map); // {2=two, 6=six}1.4.应用Map.ofEntries() 和 Map.entry()工厂办法Map.ofEntries承受Map.Entry作为varargs。还有另一个相干的新静态方法Map.entry(K, V)来创立Entry实例。 ...

October 18, 2020 · 1 min · jiezi

关于spring:10年经验17张图带你进入gitflow企业项目代码版本管理的最佳实践

前言对于我的项目版本治理,你是否存在这样的痛点:我的项目分支多而杂不好治理,git log界面commit信息错乱简单无标准,版本回退不晓得抉择什么版本适合……。我的项目版本治理的最佳实际系列,笔者将以两篇文章的模式开展介绍(即根底篇与进阶篇)。本文为gitflow版本治理的最佳实际-根底篇。根底篇次要介绍git利用于生产的根本流程与怎么应用gitflow治理你的我的项目版本线(实用于麻利迭代的项目管理场景下)。进阶篇 将着重介绍gitflow+jenkins+docker+DevOps+麻利Scrum 实现我的项目继续构建与继续交付(CI/CD)。浏览本文须要有肯定git根底,基础知识则不在本文开展,善用网上冲浪工具便可学习到许多Git的基础知识。实际上,本文介绍的并不是纯正的gitflow,而是结合实际生产对gitflow的革新与最佳实际。 Git的根本术语与简写术语解释PR即pull request,拉取申请。申请git代码管理员将你的代码合并到仓库的分支中。个别的PR由题目局部,形容局部与代码局部组成。code review在PR过程中代码管理员对你提交的代码进行代码审查,即你的代码是否符合规范、是否存在格调问题、平安问题等,对你代码进行cr的同学并不一定是代码管理员,成熟的麻利团队,每一个成员都是code owner,都能够对pr进行审阅。squashPR过程中,会将你的所有commit合并(榨取)成一个commit并提交到指标分支中,目标是缩小冗余提交、标准主分支提交信息(实际上是rebase的一种操作)。LGTMlook good to me(看起来很吊),个别存在于PR评论中,即对pr的内容没有问题,批准合并到版本库。一、分支规约在咱们的最佳实际中,近程版本库永远只存在三条长期且互相独立的分支,他们别离为develop、release与master,三条分支对应三个环境,别离为开发环境(集成开发环境)、测试环境(预发环境)与生产环境,三个分支别离都上权限,不可间接对其进行push与commit操作,即所有的批改均通过PR进行,以保障分支对应环境的平安与稳固。本地环境对应的近程分支均会在PR通过之后,主动进行删除,以保障版本线的简略。 环境分支名开发环境origin/develop测试环境(预发环境)origin/release生产环境origin/master本地环境性能分支develop_xxx (xxx为具体的开发成员或具体的性能形容, origin/develop_xxx,即feature分支下沉到本地,生命周期短,只存在于pr过程)。二、版本号规约在正式介绍gitflow之前,咱们须要对版本号进行标准,不便接下来的行文开展。 在生产中,咱们罕用的版本号为三位数版本号(偶然带四位热修复号),其形成如下: V主版本号.次版本号.性能号(.${热修复版本号}).环境eg:V1.0.0.1.RELEASE、V1.1.0.DEVELOP、V1.0.0。(版本号并不以十进制,而是依照迭代布局推送) 2.1 主版本号(首位版本号)主版本号,也叫首位版本号、顶位版本号,即V后第一个版本号。主版本号个别代表我的项目的期数与产品方向。除非我的项目合同扭转、大规模api不兼容、产品方向扭转、底层架构降级等状况外不轻易更新。 另外,我的项目未正式公布、未正式孵化、未正式上线,则首位版本号为0,一期公布,则为V1。 2.2 次版本号(迭代号)次版本号,也叫迭代号,个别代表某个迭代公布的性能汇合(一个迭代发布会蕴含若干个性能更新)。 如V1.1.0:第一期我的项目第一迭代公布版本、V1.2.0:第一期第二迭代公布版本。 2.3 性能号(PR号)一般来说,提交到我的项目分支内的代码均须要通过PR,而为了保障单个PR的简洁性与纯正性,倡议一个PR形容一个性能。因而第三位数的版本号也叫做PR号或性能号,用来形容单个提交到主分支内的性能或代码批改。 如V0.0.1:第一迭代的第一个提交、V0.0.98:第一迭代的第98个PR。 2.4 热修复号四位数版本号是可选版本号,为热修复版本号(也叫老爷保号hh),惯例迭代与develop分支下并不会呈现,而常呈现在测试环境对应的release分支与生产环境对应的master分支(develop分支对应的开发环境呈现bug间接提交pr修复并在原来的版本号上+1便可)。这个版本号罕用于线上热修复,测试环境(预发环境)的热修复。 值得注意的是,四位数版本号通过线上热修复之后,要同步到本地develop环境的状况下,该当在develop分支下的三位数版本号上加一。 如:master的热修复号为V1.0.0.4,develop分支以后版本为V1.1.8.DEVELOP,那么这个修复要同步回develop分支保障bug不重现,那么在develop下面的版本则为V1.1.9.DEVELOP 2.5 环境号因为在git中的tag名称是惟一的,那么在develop分支下呈现了V1.0.0的tag,那么在release和master下便不能够再打一个tag叫V1.0.0。因而呈现环境号来对分支版本进行辨别(生产环境不加环境号)。 环境环境名版本号(示例)开发环境DEVELOPV1.0.0.DEVELOP测试环境(预发环境)RELEASEV1.0.0.RELEASE生产环境MASTERV1.0.0三、Gitflow的最佳实际3.1 总体流程图 3.2 最佳实际举例这里要搬出两位同学进行接下来的解说,他们是【弓行】同学与【阿康】同学。 3.2.1 近程骨干分支创立版本的最开始(指V0.0.0),代码管理员会初始化近程仓库,并基于master的初始版本创立三条分支,他们是: origin/master(对应生产),origin/release(对应测试环境),origin/develop(对应开发环境) 并为这三条分支设置爱护策略,三条分支均不容许间接的commit与push批改。 代码管理员将三个初始版本打上相应的TAG:(V0.0.0.DEVELOP、V0.0.0.RELEASE与V0.0.0)。 3.2.2 本地分支创立实现迭代打算会议(迭代版本号为V0.1.0)之后,弓行与阿康他们别离认领了两个工作:【开发性能】弓行,【开发性能2】阿康。 此时,弓行与阿康会将近程仓库克隆下来,并基于origin/develop 创立本地develop_gx分支与develop_kang分支。 3.2.3 创立PR两人认领工作后进行同步开发,一段时间后,弓行率先实现【开发性能1】的工作,因而他须要将以后开发版本提交到开发环境中进行自测与前后端联调。但此时【origin/develop】是被爱护的状态无奈被间接提交。因而,弓行须要对以后的开发的版本进行PR申请,即创立拉取申请,申请代码管理员对代码进行code review,通过后进行合并。 此处波及的步骤大抵如下: 1、push以后本地分支到origin,失去origin/develop_gx。 2、创立PR:即:origin/develop_gx 合并到 origin/develop 的拉取申请 3、期待代码管理员(或小组内同学)进行code review,若须要批改,则间接在pr中提出正文,作者批改后间接push到近程分支中,持续期待代码管理员进行code review。 4、通过后,将以后commit list以squash的模式合并到origin/develop中,失去V0.0.1.DEVELOP 的commit 5、最初抉择删除origin/develop_gx的近程分支 此时,弓行同学实现了第一个性能的开发,并在【origin/develop】分支上对本人的pr commit 进行tag操作:将此commit记录为【V0.0.1.DEVELOP】 ...

October 17, 2020 · 2 min · jiezi

关于spring:Java9第四篇Reactive-Stream-API响应式编程

我打算在后续的一段时间内,写一系列对于java 9的文章,尽管java 9 不像Java 8或者Java 11那样的外围java版本,然而还是有很多的个性值得关注。期待您能关注我,我将把java 9 写成一系列的文章,大略十篇左右。 java9第一篇-能够在interface中定义公有办法了java9第二篇-Java9改良try-with-resources语法java9第三篇-反对多JDK版本下运行的Jar文件打包形式Java 9的 Reactive Streams是对异步流式编程的一种实现。它基于异步公布和订阅模型,具备非阻塞“背压”数据处理的特点。 Non-blocking Back Pressure(非阻塞背压):它是一种机制,让公布订阅模型中的订阅者防止接管大量数据(超出其解决能力),订阅者能够异步告诉发布者升高或晋升数据生产公布的速率。它是响应式编程实现成果的外围特点! 一、Java9 Reactive Stream APIJava 9提供了一组定义响应式流编程的接口。所有这些接口都作为动态外部接口定义在java.util.concurrent.Flow类外面。 上面是Java 响应式编程中的一些重要角色和概念,先简略了解一下 发布者(Publisher)是潜在的有限数量的有序数据元素的生产者。 它依据收到的需要(subscription)向以后订阅者公布肯定数量的数据元素。订阅者(Subscriber)从发布者那里订阅并接收数据元素。与发布者建设订阅关系后,发布者向订阅者发送订阅令牌(subscription),订阅者能够依据本人的解决能力申请发布者公布数据元素的数量。订阅令牌(subscription)示意订阅者与发布者之间建设的订阅关系。 当建设订阅关系后,发布者将其传递给订阅者。 订阅者应用订阅令牌与发布者进行交互,例如申请数据元素的数量或勾销订阅。二、Java响应式编程四大接口2.1.Subscriber Interface(订阅者订阅接口)public static interface Subscriber<T> { public void onSubscribe(Subscription subscription); public void onNext(T item); public void onError(Throwable throwable); public void onComplete();}onSubscribe:在发布者承受订阅者的订阅动作之后,公布任何的订阅音讯之前被调用。新创建的Subscription订阅令牌对象通过此办法传递给订阅者。onNext:下一个待处理的数据项的处理函数onError:在发布者或订阅遇到不可复原的谬误时调用onComplete:当没有订阅者调用(包含onNext()办法)产生时调用。2.2.Subscription Interface (订阅令牌接口)订阅令牌对象通过Subscriber.onSubscribe()办法传递 public static interface Subscription { public void request(long n); public void cancel();}request(long n)是无阻塞背压概念背地的要害办法。订阅者应用它来申请n个以上的生产我的项目。这样,订阅者管制了它以后可能接管多少个数据。cancel()由订阅者被动来勾销其订阅,勾销后将不会在接管到任何数据音讯。2.3.Publisher Interface(发布者接口)@FunctionalInterfacepublic static interface Publisher<T> { public void subscribe(Subscriber<? super T> subscriber);}调用该办法,建设订阅者Subscriber与发布者Publisher之间的音讯订阅关系。 ...

October 17, 2020 · 1 min · jiezi

关于spring:一起来读官方文档SpringIOC09

1.10。Classpath Scanning and Managed Components本章中的大多数示例应用XML配置。 上一节(基于注解的容器配置)演示了如何通过注解配置bean。虽说是注解配置,但根本”bean”定义也显式地定义在XML文件中,而注解仅驱动依赖项注入。 本节形容通过扫描classpath隐式检测候选Spring组件。 候选组件是指满足筛选规范的类,并有相应的bean definition 注册到容器中。 这样就不须要应用XML来执行bean注册。 相同,您能够应用注解(例如@Component)、AspectJ类型表达式或您本人的自定义筛选规范来抉择哪些类曾经向容器注册了bean定义。 从Spring 3.0开始,Spring JavaConfig我的项目提供的许多个性都是外围Spring框架的一部分。这容许您应用Java而不是传统的XML文件定义bean。比方:@Configuration、@Bean、@Import和@DependsOn1.10.1。@Component和构造型注解@Repository注解是满足存储库角色或构造型的任何类的标记(也称为数据拜访对象或DAO)。 该标记的应用还能够进行异样的主动翻译,能将所标注的类中抛出的数据拜访异样封装为Spring的数据拜访异样类型。 Spring提供了进一步的构造型注解:@Component, @Service和@Controller。 @Component是任何spring治理组件的通用原型。 @Repository、@Service和@Controller则是针对更具体用例(别离在持久性、服务和表示层中),它们是@Component的细化。 因而,您能够应用@Component来注解组件类,然而,通过应用@Repository、@Service或@Controller来注解它们,您的类更适宜通过工具进行解决或与方面关联。 例如,这些构造型注解是AOP切点的现实指标。 @Repository、@Service和@Controller还能够在Spring框架的将来版本中附带额定的语义,就像@Repository的异样翻译一样。 因而,如果您要在您的服务层应用@Component或@Service之间进行抉择,那么@Service显然是更好的抉择。 相似地,如前所述,@Repository曾经被反对作为长久化层中主动异样转换的标记。 1.10.2。应用元注解和组合注解Spring提供的许多注解都能够在您本人的代码中用作元注解。 元注解是能够利用于另一个注解的注解。 例如,@Service注解上存在元注解@Component,如上面的示例所示: @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Component public @interface Service { // ...}//@Component的存在导致Spring以@Component的形式来看待@Service。您还能够联合应用元注解来创立“组合注解”。 例如,Spring MVC中的注解 @RestController 由@Controller和 组成@ResponseBody。 此外,组合注解能够抉择从元注解中从新申明属性,以容许自定义。 当您只心愿公开元注解属性的子集时,这特地有用。 例如,Spring的 @SessionScope注解将@Scope的value属性硬编码为session,但仍容许自定义@Scope的proxyMode。 以下清单显示了SessionScope注解的定义 : @Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@Scope(WebApplicationContext.SCOPE_SESSION)public @interface SessionScope { /** * Alias for {@link Scope#proxyMode}. * <p>Defaults to {@link ScopedProxyMode#TARGET_CLASS}. */ @AliasFor(annotation = Scope.class) ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;}而后,您@SessionScope无需申明proxyMode以下即可应用: ...

October 16, 2020 · 3 min · jiezi

关于spring:Java9系列第三篇同一个Jar支持多JDK版本运行

我打算在后续的一段时间内,写一系列对于java 9的文章,尽管java 9 不像Java 8或者Java 11那样的外围java版本,然而还是有很多的个性值得关注。期待您能关注我,我将把java 9 写成一系列的文章,大略十篇左右。 java9第一篇-能够在interface中定义公有办法了java9第二篇-Java9改良try-with-resources语法本文内容:在Java 9加强了JAR多版本字节码文件格式的反对,同一个Jar包能够蕴含多个Java版本的class文件。应用这个性能,咱们能够将应用程序/库降级到新的Java版本,而不用强制用户降级到雷同的Java版本。 一、根本应用办法多版本的字节码发行jar包,须要在其MANIFEST.MF中做以下的申明: Multi-Release: true在jar包的META-INF/versions文件目录外面能够蕴含多个版本的class文件,编译后果目录构造如下: jar root - A.class - B.class - META-INF - versions - 9 - A.class假如上文中的根目录是应用java 8 或之前版本编译的字节码文件A.calss。META-INF/versions/9/ 是应用java 9 编写的java代码的编译后果A.class。 如果jar包是在JDK 8的运行时环境下运行,将应用根目录上面的class文件进行程序运行。如果jar包是在JDK 9的运行时环境下运行,将应用META-INF/versions/9/ 上面的class文件进行程序运行。假如将来这个我的项目降级JDK 10,决定在A.java中应用Java 10的一些新个性,能够独自针对A.class进行语法降级,并将编译后果a.class搁置在META-INF/versions/10/ 上面 jar root - A.class - B.class - META-INF - versions - 9 - A.class - 10 - A.class当初,下面的jar蕴含了能够以三种Java版本运行的字节码文件,A.class兼容JDK 8、9、10。 二、实在的例子java 8代码上面的类文件代码咱们让它运行在Java 8的环境下 package com.example;public class IOUtil { public static String convertToString(InputStream inputStream) throws IOException { System.out.println("IOUtil 应用java 8 版本"); Scanner scanner = new Scanner(inputStream, "UTF-8"); String str = scanner.useDelimiter("\\A").next(); scanner.close(); return str; }}减少一个Main.java的应用程序入口文件,调用IOUtil.convertToString办法将InputStream转换成String。 ...

October 16, 2020 · 1 min · jiezi

关于spring:Spring-学习记录三

1.AOP记录Aspectj切入点:罕用表达式execution(<拜访修饰符>?<返回类型><参数><异样>)(1)execution(* cn.aop.Book.add(..))(2)execution( cn.aop.Book.(..))(3)execution( .*(..))所有类办法2.Aspectj的AOP操作(1)配置文件操作(2)注解操作首先开启主动代理<aop:aspectj-autoproxy>其次,用注解的形式在加强类及办法上退出注解:3.jdbcTemplate(1)设置数据库(2)创立jdbcTemplate;(3)写sql(4)调用jdbcTempalte办法;前两步可通过配置文件实现。4.Spring事务管理(1)配置文件形式:第一步配置事务管理器,不须要变;第二步只须要批改事务操作的办法 account*(作用于办法名为account结尾的)第三步只须要批改切入点~~~~(2)注解形式:略

October 15, 2020 · 1 min · jiezi

关于spring:1T数据快速排序十种经典排序算法总结

1 冒泡排序每次循环都比拟前后两个元素的大小,如果前者大于后者,则将两者进行替换。这样做会将每次循环中最大的元素替换到开端,逐步造成有序汇合。将每次循环中的最大元素逐步由队首转移到队尾的过程形似“冒泡”过程,故因而得名。 一个优化冒泡排序的办法就是如果在一次循环的过程中没有产生替换,则能够立刻退出以后循环,因为此时曾经排好序了(也就是工夫复杂度最好状况下是的由来)。 public int[] bubbleSort(int[] array) { if (array == null || array.length < 2) { return array; } for (int i = 0; i < array.length - 1; i++) { boolean flag = false; for (int j = 0; j < array.length - 1 - i; j++) { if (array[j] > array[j + 1]) { //这里替换两个数据并没有应用两头变量,而是应用异或的形式来实现 array[j] = array[j] ^ array[j + 1]; array[j + 1] = array[j] ^ array[j + 1]; array[j] = array[j] ^ array[j + 1]; flag = true; } } if (!flag) { break; } } return array;}2 抉择排序每次循环都会找出以后循环中最小的元素,而后和此次循环中的队首元素进行替换。 ...

October 15, 2020 · 9 min · jiezi

关于spring:手把手教你用-Spring-Boot搭建一个在线文件预览系统支持pptdoc等多种类型文件预览

昨晚搭建环境都花了好一会工夫,次要在节约在了装置 openoffice 这个依赖环境上(_Mac 须要手动装置_)。而后,又一步一步性能演示,记录,调试我的项目,并且简略钻研了一下外围代码之后才把这篇文章写完。 另外,这篇文章我还会简略剖析一下我的项目外围代码。 如果有帮忙,欢送点赞/再看激励,我会开心很久 ( ´・・` )比心 我的项目介绍官网是这样介绍 kkFileView 的: kkFileView 是应用 spring boot 打造文件文档在线预览我的项目解决方案,反对 doc、docx、ppt、pptx、xls、xlsx、zip、rar、mp4、mp3 以及泛滥类文本如 txt、html、xml、java、properties、sql、js、md、json、conf、ini、vue、php、py、bat、gitignore 等文件在线预览简略来说 kkFileView 就是常见的文件类型的在线预览解决方案。 总的来说我感觉 kkFileView 是一个十分棒的开源我的项目,在线文件预览这个需要十分常见。感激开源! 上面, 我站在一个“上帝”的角度从多个维度来评估一下 kkFileView: 代码品质个别,有很多能够优化的中央比方: Controller 层代码嵌套太多逻辑没有进行全局异样解决(_代码中是间接返回错误信息的 json 数据给前端,我并不举荐这样做_)返回值不须要通过ObjectMapper转换为 JSON 格局(ResponseEntity+@RestController 就行了)......应用的公司比拟多,阐明我的项目整体性能还是比较稳定和成熟的!代码整体逻辑还是比拟清晰的,比拟容易看懂,给作者们点个赞!环境搭建克隆我的项目通过以下命令即可将我的项目克隆到本地: git clone https://gitee.com/kekingcn/file-online-preview.git装置 OpenOfficeoffice 类型的文件的预览依赖了 OpenOffice ,所以咱们首先要装置 OpenOffice(Windows 下已内置,Linux 会主动装置,Mac OS 下须要手动装置)。 上面演示一下如何在 Mac 上装置 OpenOffice。 你能够通过以下命令装置最新版的 OpenOffice: brew cask install openoffice不过,这种形式下载可能会比较慢,你能够间接去官网下载 dmg 安装包。 官网下载地址:https://www.openoffice.org/download/ 很多小伙伴就要问了:OpenOffice 是什么呢? OpenOffice 是 Apache 旗下的一款开源收费的文字处理软件,反对 Windows、Liunx、OS X 等支流操作系统。 ...

October 15, 2020 · 3 min · jiezi

关于spring:编程体系结构08SpringMvcBoot框架

本文源码:GitHub·点这里 || GitEE·点这里 一、Spring框架 1、框架概述 Spring是一个开源框架,框架的次要劣势之一就是其分层架构,分层架构容许使用者抉择应用哪一个组件,同时为 J2EE 利用程序开发提供集成的框架。Spring应用根本的JavaBean来实现以前只可能由EJB实现的事件。Spring是一个分层的轻量级开源框架。 根本个性:分层架构、高内聚低耦合、反对AOP编程、事务管理、集成测试、集成各种框架。 2、外围组件 外围容器:蕴含Bean的创立、配置、治理等性能。 AOP切面编程:能够帮忙应用程序解耦。 数据拜访:集成了JDBC,罕用的Dao层框架hibernate,mybatis等。 Web编程:集成流程的MVC框架,实现界面逻辑和应用程序拆散。 3、Bean对象了解 Spring容器负责创立,拆卸,设置属性,进而治理整个生命周期的对象,称为Bean对象。 拆卸形式:XML格局、注解扫描、Java代码拆卸。 作用域:用于确定spring创立bean实例个数,比方单例Bean,原型Bean。singleton默认单例、prototype多例、request申请、session会话级、global-session。 生命周期:实例化,属性加载,初始化前后治理,销毁。 4、罕用外围注解 Controller:标记一个类是Handler,基于@Mapping相干注解(@GetMapping、@PostMapping、@PutMapping、@DeleteMapping),用来关联申请和Controller办法之间的映射关系,这样的Controller 就能够被申请拜访。 RequestMapping:解决申请地址映射的注解,可作用于类或办法上。用于类上,示意类中的所有响应申请的办法都是以类上标注地址作为父门路。 Resource:依照ByName主动注入,须要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。 Service:能够取代具体配置文件的Bean治理,定义的bean默认是单例的,默认名称是类名且首字母小写。 5、IOC与DI思维 IOC容器 Java零碎中对象耦合关系十分复杂,零碎的各模块之间依赖,微服务模块之间的互相调用申请,都是这个情理。升高零碎模块之间、对象之间、微服务的服务之间耦合度,是软件工程外围问题之一。因为Spring框架中核心思想就是IOC管制反转,用来实现对象之间的解耦。 依赖注入 IOC给对象间接建设关系的动作,称为DI依赖注入(Dependency Injection);依赖:对象A须要应用对象B的性能,则称对象A依赖对象B。注入:在对象A中实例化对象B,从而应用对象B的性能,该动作称为注入。 6、Aop切面编程 通过预编译形式和运行期动静代理实现程序性能的对立保护的一种技术。核心作用:能够对业务逻辑的各个局部进行隔离,从而使得业务逻辑各局部之间的耦合度升高,进步程序的复用性和开发效率。AOP提供了取代继承和委托的一种新的计划,而且应用起来更加简洁清晰,是软件开发中的一个热点理念。 实现形式:JDK动静代理、CgLib字节码加强、Spring半自动代理、Spring全自动代理。 7、事务管理 事务是指作为单个逻辑工作单元执行的一系列操作(SQL语句)。这些操作要么全副胜利,要么全副不胜利。Spring事务管理的实质就是封装了数据库对事务反对的操作,应用JDBC的事务管理机制,就是利用java.sql.Connection对象实现对事务的提交和回滚。 外围API封装 PlatformTransactionManager:平台事务管理器,Spring治理事务,必须应用事务管理器进行事务配置时,外围办法:获取事务,提交事务,回滚事务。 TransactionDefinition:该对象封装事务详情(事务定义、事务属性),例如:隔离级别、是否只读、超时工夫 等。 TransactionStatus:用于记录以后事务运行状态。例如:是否有保留点,事务是否实现。Spring底层依据状态进行相应操作。 8、配置文件 在Spring的配置文件中,通常会配置下列核心内容; 读取内部配置文件,例如JDBC参数;配置数据库连接池,例如Druid、C3P0等;整合环境配置,例如SSM或者SSH集成;治理Transaction事务的管制形式;整合罕用组件,例如邮件、工作、MQ等;在理论开发中,简单的我的项目配置非常繁冗且不好治理,可能我的项目中波及不同环境的配置文件都有几十个,所在在SpringBoot框架中采纳对立约定的形式简化。 9、环境整合SSM、SSH Spring框架聚合很强的整合能力,例如常见的整合Mybatis,Mvc,Hibernate,Redis等系列组件,为开发环境的集成提供很大的便当,整体职责上分为几层:管制层、业务逻辑层、数据长久层、域模块层、中间件层,以帮忙开发人员在短期内搭建构造清晰、可复用性好、保护不便的Web应用程序。 10、设计模式 单例模式:Spring框架中Bean对象的治理,默认单例,也能够显式标识为多例模式。 工厂模式:通过对应的工厂来生成类的对象,这种设计形式合乎“开闭”准则。Spring框架中BeanFactory和Bean的用法。 适配器模式:SpringMvc执行管制中,前段控制器DispatcherServlet调用处理器适配器去执行Handler,处理器适配器去执行Handler,给适配器返回ModelAndView。 责任链模式:DispatcherServlet外围办法doDispatch。HandlerExecutionChain只是保护HandlerInterceptor的汇合,能够向其中注册相应的拦截器,自身不间接解决申请,将申请调配给责任链上注册处理器执行,升高职责链自身与解决逻辑之间的耦合水平。 二、SpringMvc模式1、Mvc模式理念 SpringMVC是一种基于Java实现的MVC设计模式的申请驱动类型的轻量级Web框架,出自Spring框架全家桶,与Spring框架无缝整合,应用了MVC架构模式的思维,将Web层进行职责解耦。构造涣散,简直能够在SpringMVC中应用各类视图,各个模块拆散而且耦合度非常低,且易于扩大。与Spring无缝集成,且简略,灵便,容易上手。 2、执行流程 发动申请到前端控制器DispatcherServlet;前端控制器申请HandlerMapping查找,Handler能够依据xml配置、注解进行查找; 处理器映射器HandlerMapping向前端控制器返回Handler;前端控制器调用处理器适配器去执行Handler;处理器适配器去执行Handler; Handler执行实现给适配器返回ModelAndView;处理器适配器向前端控制器返回ModelAndView,ModelAndView是springmvc框架的一个底层对象,包含Model和view; 前端控制器申请视图解析器去进行视图解析,依据逻辑视图名解析成真正的视图;视图解析器向前端控制器返回View;前端控制器进行视图渲染,视图渲染将模型数据(在ModelAndView对象中)填充到request域中;前端控制器向用户响应后果; 3、外围组件 前端控制器:申请来到浏览器后,最先达到的就是DispatcherServlet,是整个流程管制的核心。 处理器映射器:依据申请的url路由到指定接口,用户申请找到Handler处理器。 处理器适配器:依照特定规定去执行Handler,反对多种处理器,各种处理器中的解决办法各不相同。 处理器:解决用户申请,波及具体业务逻辑,须要依据业务需要开发。 视图解析器:将申请的响应后果生成View,依据逻辑视图名解析成物理视图名,就是具体页面地址。 ...

October 15, 2020 · 1 min · jiezi

关于spring:java9系列第二篇资源自动关闭的语法增强

我打算在后续的一段时间内,写一系列对于java 9的文章,尽管java 9 不像Java 8或者Java 11那样的外围java版本,然而还是有很多的个性值得关注。期待您能关注我,我将把java 9 写成一系列的文章,大略十篇左右。 java9第一篇-能够在interface中定义公有办法了在Java 9的版本中,对从JDK 7开始反对的try-with-resources语法进行了改良。尽管只是一个小小的改良,我仍心愿把他介绍给你,咱们一起来每天提高一点点。 一、先说Java7的try-with-resources(Java9改进版在后文)在Java 7之前没有try-with-resources语法,所有的流的销毁动作,全都须要本人在finally办法中手动的写代码进行敞开。如下文中的代码,将一个字符串写入到一个文件外面。 @Testvoid testStream() throws IOException { String fileName = "D:\\data\\test\\testStream.txt"; FileOutputStream fos = new FileOutputStream(fileName); //创立IO管道流 OutputStreamWriter osw = new OutputStreamWriter(fos); BufferedWriter bw = new BufferedWriter(osw); try{ bw.write("手写代码进行Stream流的敞开"); bw.flush(); }finally{ bw.close(); //手动敞开IO管道流 osw.close(); fos.close(); }}从Java 7版本开始提供了try-with-resources语法,咱们只须要把管道流用try()蕴含起来,在try代码段执行实现之后,IO管道流就会主动的敞开,不须要咱们手写代码去敞开,这很简洁! @Testvoid testTry() throws IOException { String fileName = "D:\\data\\test\\testTry.txt"; try(FileOutputStream fos = new FileOutputStream(fileName); OutputStreamWriter osw = new OutputStreamWriter(fos); BufferedWriter bw = new BufferedWriter(osw);){ bw.write("IO管道流被主动调用close()办法"); bw.flush(); }}二、防止走入误区很多小伙伴在晓得try-with-resources语法之后,容易陷入误区 ...

October 15, 2020 · 1 min · jiezi

关于spring:一起来读官方文档SpringIOC08

1.9。基于注解的容器配置 注解在配置Spring方面比XML更好吗?基于注解的配置的引入提出了一个问题,即这种办法是否比XML“更好”。简短的答案是“取决于状况”。长话短说,每种办法都有其优缺点,通常,由开发人员决定哪种策略更适宜他们。因为定义形式的不同,注解在申明中提供了很多上下文,从而使配置更短,更简洁。然而,XML善于连贯组件而不接触其源代码或从新编译它们。一些开发人员更喜爱将布线搁置在凑近源的地位,而另一些开发人员则认为带注解的类不再是POJO,而且,该配置变得扩散且难以管制。无论抉择如何,Spring都能够包容两种款式,甚至能够将它们混合在一起。值得指出的是,通过其JavaConfig选项,Spring容许以非侵入形式应用注解,而无需接触指标组件的源代码。注解是XML配置的代替办法,该配置依赖字节码元数据来连贯组件,而不是尖括号申明。 通过应用相干的 类,办法或字段 申明上的注解,开发人员无需应用XML来形容bean的连贯,而是将配置移入组件类自身。 如示例中所述:将RequiredAnnotationBeanPostProcessor,通过BeanPostProcessor的形式与注解联合应用是扩大Spring IoC容器的罕用办法。 例如,Spring 2.0引入了应用@Required注解强制执行必须属性的可能性。 Spring 2.5引入@Autowired注解,提供的性能与主动拆卸合作器中所述的性能雷同,但具备更细粒度的管制和更宽泛的适用性。Spring 2.5还增加了对JSR-250批注(例如 @PostConstruct和@PreDestroy)的反对。 Spring 3.0减少了对javax.inject包中蕴含的JSR-330(Java依赖性注入)注解的反对,例如@Inject 和@Named。注解注入在XML注入之前执行。因而,XML配置将笼罩通过注解注入的属性 与平常一样,您能够依据类名将它们注册为独自的bean定义,但也能够通过在基于XML的Spring配置中蕴含以下标记来隐式注册它们: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/></beans><context:annotation-config/> 隐式注册后置处理器包含 : AutowiredAnnotationBeanPostProcessor CommonAnnotationBeanPostProcessor PersistenceAnnotationBeanPostProcessor RequiredAnnotationBeanPostProcessor并且当应用<context:component-scan/>后,即可将<context:annotation-config/>省去<context:annotation-config/>只在定义它的雷同应用程序上下文中查找对于bean的注解。 这意味着,如果你把<context:annotation-config/>定义在WebApplicationContext的DispatcherServlet中,它只是查看controllers中的@Autowired注解,而不是你的services。 上边的这段话意思不是很明确,须要解释一下以前用web.xml配置时的Spring启动流程拿出几段配置<!--配置开始 --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/service/*</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:spring/spring-base.xml </param-value> </context-param><!--配置完结 -->上边的配置应该是多年前webi利用的根底配置,理一下tomcat启动后如何调用Spring的大略流程1. tomcat读取web.xml文件(此处不论tomcat如何找到xml),解析内容并分组,分成ServletContainerInitializer,servlet,listener,context-param等多个数组2.一一进行解析,先解析ServletContainerInitializer //这个就相当典型了 这个货色就是之前的文章讲过的ServletContainerInitializer //Tomcat启动会查找ServletContainerInitializer实现类并执行其中的onStartup办法。 //Spring-web模块存在ServletContainerInitializer实现类,所以Tomcat启动会调用Spring-web的代码。 //然而咱们用Spring框架的话不须要实现这个接口,实现一个Spring的接口WebApplicationInitializer。 //就能够由Tomcat调用Spring-web的ServletContainerInitializer实现类 Iterator i$ = this.initializers.entrySet().iterator(); while(i$.hasNext()) { Entry entry = (Entry)i$.next(); try { ((ServletContainerInitializer)entry.getKey()).onStartup((Set)entry.getValue(), this.getServletContext()); } catch (ServletException var22) { log.error(sm.getString("standardContext.sciFail"), var22); ok = false; break; } }然而这里咱们并没有用这种形式而是用了listener的形式持续往下看3. 解析listener,这里this.listenerStart()会解析咱们配置的ContextLoaderListener if (ok && !this.listenerStart()) { log.error(sm.getString("standardContext.listenerFail")); ok = false; } 就在这里tomcat关联上了Spring的ApplicationContext,会实例化XmlWebApplicationContext, 实例化时取出context-param中的name为contextConfigLocation的配置文件,来进行解析注册 4.解析servlet,this.loadOnStartup(this.findChildren())来解析servlet, if (ok && !this.loadOnStartup(this.findChildren())) { log.error(sm.getString("standardContext.servletFail")); ok = false; }这里就会进入DispatcherServlet的init办法,init办法中会依据以后的ServletContext查找在此之前有没有初始化过Spring的ApplicationContext,而后再判断以后DispatcherServlet有没有ApplicationContext,如果没有就初始化一个并把之前初始化ApplicationContext的设置为父节点总结一下,也就是说用了上边的配置的话,tomcat在启动过程中,会初始化两遍并生成两个ApplicationContext对象,第一遍解析context-param中param-name 为contextConfigLocation的配置文件, 并以此配置文件生成一个ApplicationContext ROOT第二遍是解析DispatcherServlet servlet的spring-mvc.xml配置文件, 再以此配置文件生成一个ApplicationContext,并将ROOT设置为父节点因而就产生了一个问题,当你在两个ApplicationContext都能够扫描到同一个Bean的时候,那么这个bean在连个ApplicationContext中都各存在一个实例,并且实例不一样举一个之前遇到的问题: 之前想给某个controller加一个AOP,拦挡某些办法进行非凡解决,然而我把 <aop:aspectj-autoproxy/>这个注解 放到了上面这个档次的配置文件中了 <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:spring/spring-base.xml </param-value> </context-param> 最初我的AOP并没有失效,起初又把注解挪到了spring-mvc.xml中,才失效。 之前百度搜到说:spring-mvc 的配置扫描优先于spring的配置文件 通过调试才了解这句话: 我的controller在spring的ApplicationContext中有一份被AOP代理的对象 在spring-mvc的ApplicationContext中还有一份没被代理的一般对象 因为spring-mvc配置加载的晚,所以用到的都是没有被代理的对象1.9.1。@Required该@Required注解实用于bean属性setter办法,如上面的例子: ...

October 14, 2020 · 6 min · jiezi

关于spring:手写一个HTTP框架两个类实现基本的IoC功能

jsoncat: 仿 Spring Boot 但不同于 Spring Boot 的一个轻量级的 HTTP 框架国庆节的时候,我就曾经把 jsoncat 的 IoC 性能给写了,具体能够看这篇文章《手写“SpringBoot”近况:IoC模块曾经实现》 。 明天这篇文章就来简略分享一下本人写 IoC 的思路与具体的代码实现。 IoC (Inverse of Control:管制反转) 和 AOP(Aspect-Oriented Programming:面向切面编程) 能够说是 Spring 框架提供的最外围的两个性能。但但凡理解过 Spring 的小伙伴,那必定对这个两个概念十分十分理解。不理解的小伙伴,能够查看《面试被问了几百遍的 IoC 和 AOP ,还在傻傻搞不清楚?》这篇通俗易懂的文章。 思考到这篇文章要手写 Spring 框架的 IoC 性能,所以,我这里还是简略介绍一下 IoC 。如果你不太分明 IoC 这个概念,肯定要搞懂之后再看前面具体的代码实现环节。 IoC 介绍IoC(Inverse of Control:管制反转)是一种设计思维,也就是 将本来在程序中手动创建对象的控制权交由Spring框架来治理。 IoC 在其余语言中也有利用,并非 Spring 特有。 IoC 容器IoC 容器是用来实现 IoC 的载体,被治理的对象就被寄存在IoC容器中。IoC 容器在 Spring 中实际上就是个Map(key,value),Map 中寄存了各种被治理的对象。 IoC 解决了什么问题将对象之间的相互依赖关系交给 IoC 容器来治理,并由 IoC 容器实现对象的注入。这样能够很大水平上简化利用的开发,把利用从简单的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当咱们须要创立一个对象的时候,只须要配置好配置文件/注解即可,齐全不必思考对象是如何被创立进去的。 在理论我的项目中一个 Service 类可能有几百甚至上千个类作为它的底层,如果咱们须要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只须要配置好,而后在须要的中央援用就行了,这大大增加了我的项目的可维护性且升高了开发难度。 ...

October 14, 2020 · 4 min · jiezi

关于spring:推荐一款IDEA神器一键查看Java字节码以及其他类信息

因为前面要分享的一篇文章中用到了这篇文章要举荐的一个插件,所以这里分享一下。十分实用!你会爱上它的! 开始举荐 IDEA 字节码查看神器之前,先来回顾一下 Java 字节码是啥。 何为 Java 字节码?Java 虚拟机(JVM)是运行 Java 字节码的虚拟机。JVM 有针对不同零碎的特定实现(Windows,Linux,macOS),目标是应用雷同的字节码,它们都会给出雷同的后果。 什么是字节码?采纳字节码的益处是什么? 在 Java 中,JVM 能够了解的代码就叫做字节码(即扩大名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的形式,在肯定水平上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以 Java 程序运行时比拟高效,而且,因为字节码并不针对一种特定的机器,因而,Java 程序毋庸从新编译便可在多种不同操作系统的计算机上运行。Java 程序从源代码到运行个别有上面 3 步: 为什么要查看 Java 字节码?咱们在平时学习的时候,常常须要查看某个 java 类的字节码文件。查看字节码文件更容易让咱们搞懂 java 代码背地的原理比方搞懂 java 中的各种语法糖的实质。 如何查看 Java 字节码?如果咱们通过命令行来查看某个 class 的字节码文件的话,能够间接通过 javap 命令,不过这种形式太原始了,效率非常低,并且看起来不直观。 上面介绍两种应用 IDEA 查看类对应字节码文件的形式(_javap这种形式就不提了_)。 咱们以这段代码作为案例: public class Main { public static void main(String[] args) { Integer i = null; Boolean flag = false; System.out.println(flag ? 0 : i); }}下面这段代码因为应用三目运算符不当导致诡异了 NPE 异样。为了搞清楚事件的起因,咱们来看其对应的字节码。 ...

October 13, 2020 · 1 min · jiezi

关于spring:我要告诉你java接口中可以定义private私有方法

在传统的Java编程中,被广为人知的一个知识点是:java Interface接口中不能定义private公有办法。只容许咱们定义public拜访权限的办法、形象办法或静态方法。然而从Java 9 开始,Interface 接口中容许定义公有办法和公有静态方法。上面咱们就来为大家介绍其语法规定,和为什么要有这样的设计。 其实在Java 8之前,还有另一个被广为人之的知识点:接口中所有的办法必须是abstract 形象办法。然而,从java 8开始接口中能够蕴含非abstract 办法,如下文中的default办法。这个不是咱们本文要为大家介绍的内容,如不相熟,请自行补课。一、Java 9接口定义公有办法从Java 9开始,咱们能够在Interface接口中增加private的公有办法和公有静态方法。这些公有办法将改善接口外部的代码可重用性。例如,如果须要两个默认办法来共享代码,则公有接口办法将容许它们共享代码,但不将该公有办法裸露给它的实现类调用(后文中会给大家举一个例子)。 在接口中应用公有办法有四个规定: 接口中private办法不能是abstract形象办法。因为abstract形象办法是公开的用于给接口实现类实现的办法,所以不能是private。接口中公有办法只能在接口外部的办法外面被调用。接口中公有静态方法能够在其余动态和非动态接口办法中应用。接口中公有非静态方法不能在公有静态方法外部应用。interface CustomInterface { public abstract void abstractMethod(); //形象办法不能是公有的 public default void defaultMethod() { privateMethod(); //能够调用接口中的公有办法 privateStaticMethod(); //能够调用接口中的公有静态方法 System.out.println("一般办法被调用"); } public static void staticMethod() { privateStaticMethod(); //public静态方法能够调用private静态方法 System.out.println("静态方法被调用"); } private void privateMethod() { System.out.println("private公有办法被调用"); } private static void privateStaticMethod() { System.out.println("private公有静态方法被调用"); }}依照下面四个规定,下面的代码定义都是正确的 二、一个例子:别离计算奇数与偶数的和接口定义如下,下文中add办法采纳了java8 的Stream流操作,别离应用lambda表达式作为过滤条件,并求和。外围是:addEvenNumbers偶数求和函数和addOddNumbers奇数求和函数,都调用了add接口公有办法。 public interface CustomCalculator { default int addEvenNumbers(int... nums) { //非形象,java8 开始能够定义default办法 return add(n -> n % 2 == 0, nums); //过滤偶数并求和,调用private公有办法 } default int addOddNumbers(int... nums) { //非形象,java8 开始能够定义default办法 return add(n -> n % 2 != 0, nums); //过滤奇数并求和,调用private公有办法 } //依照过滤条件过滤奇数或偶数并sum求和:java9开始能够定义private公有办法 private int add(IntPredicate predicate, int... nums) { return IntStream.of(nums) //java8 Stream流 .filter(predicate) //java8 predicate及过滤器 .sum(); //sum求和 }}接口实现类MainCalculator 实现CustomCalculator接口 ...

October 13, 2020 · 1 min · jiezi

关于spring:接近8000字的SpringSpringBoot常用注解总结安排

@[toc] 0.前言大家好,我是 Guide 哥!这是我的 221 篇优质原创文章。如需转载,请在文首注明地址,蟹蟹! 本文曾经收录进我的 89K Star 的 Java 开源我的项目 JavaGuide:https://github.com/Snailclimb/JavaGuide 能够毫不夸大地说,这篇文章介绍的 Spring/SpringBoot 罕用注解根本曾经涵盖你工作中遇到的大部分罕用的场景。对于每一个注解我都说了具体用法,把握搞懂,应用 SpringBoot 来开发我的项目根本没啥大问题了! 为什么要写这篇文章? 最近看到网上有一篇对于 SpringBoot 罕用注解的文章被转载的比拟多,我看了文章内容之后属实感觉品质有点低,并且有点会误导没有太多理论应用教训的人(这些人又占据了大多数)。所以,本人索性花了大略 两天工夫简略总结一下了。 因为我集体的能力和精力有限,如果有任何不对或者须要欠缺的中央,请帮忙指出!Guide 哥感激不尽! 1. @SpringBootApplication这里先独自拎出@SpringBootApplication 注解说一下,尽管咱们个别不会被动去应用它。 Guide 哥:这个注解是 Spring Boot 我的项目的基石,创立 SpringBoot 我的项目之后会默认在主类加上。 @SpringBootApplicationpublic class SpringSecurityJwtGuideApplication { public static void main(java.lang.String[] args) { SpringApplication.run(SpringSecurityJwtGuideApplication.class, args); }}咱们能够把 @SpringBootApplication看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的汇合。 package org.springframework.boot.autoconfigure;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication { ......}package org.springframework.boot;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Configurationpublic @interface SpringBootConfiguration {}依据 SpringBoot 官网,这三个注解的作用别离是: ...

October 12, 2020 · 7 min · jiezi

关于spring:在java中使用SFTP协议安全的传输文件

本文介绍在Java中如何应用基于SSH的文件传输协定(SFTP)将文件从本地上传到近程服务器,或者将文件在两个服务器之间平安的传输。咱们先来理解一下这几个协定 SSH 是较牢靠,专为近程登录会话和其余网络服务提供安全性的协定。比方:咱们购买的云服务器登陆的时候应用的协定都是ssh。ftp协定通常是用来在两个服务器之间传输文件的,然而它实质上是不平安的。那么SFTP是什么?SFTP能够了解为SSH + FTP,也就是平安的网络文件传输协定。一般来说,SFTP和FTP服务都是应用相应的客户端软件来提供服务。如果你心愿在java代码中应用SFTP协定进行平安的文件传输,那么这篇文章非常适合你。 1. 导入JSch 依赖包在maven我的项目pom.xml中导入如下的坐标,咱们应用JSch,JSch将SFTP协定封装为对应的API供咱们调用。 <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version></dependency>2. 文件传输 – JSch例子2.1 get与put办法在中JSch,咱们能够应用put和get在服务器之间进行文件传输。put办法用来将文件从本地零碎传输到近程服务器。 channelSftp.put(localFile, remoteFile);get办法将文件从近程服务器下载到本地零碎。 channelSftp.get(remoteFile, localFile);2.2 应用用户名和明码进行认证JSch jsch = new JSch();jsch.setKnownHosts("/home/zimug/.ssh/known_hosts");jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);jschSession.setPassword(PASSWORD);"/home/zimug/.ssh/known_hosts"为SSH的known_hosts文件,也就是可信近程主机的公钥保留文件。USERNAME 为用户名REMOTE_HOST近程主机的IpREMOTE_PORT近程主机端口PASSWORD近程主机登录明码2.3.应用公钥和私钥进行认证如果读者不能了解公钥和私钥的用法及含意,须要先自行补充一下SSH常识。 本地私钥–/home/登录用户名/.ssh/id_rsa近程公钥默认保留地位–~/.ssh/authorized_keysJSch jsch = new JSch();jsch.setKnownHosts("/home/zimug/.ssh/known_hosts");jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);jsch.addIdentity("/home/zimug/.ssh/id_rsa");2.4 残缺JSch文件传输示例将文件从本地零碎传输到近程服务器1.2.3.4,并应用SSH明码登陆形式进行身份验证。 import com.jcraft.jsch.*;public class SFTPFileTransfer { private static final String REMOTE_HOST = "1.2.3.4"; //近程主机ip private static final String USERNAME = ""; //登录用户名 private static final String PASSWORD = ""; //登陆密码 private static final int REMOTE_PORT = 22; //ssh协定默认端口 private static final int SESSION_TIMEOUT = 10000; //session超时工夫 private static final int CHANNEL_TIMEOUT = 5000; //管道流超时工夫 public static void main(String[] args) { String localFile = "/home/zimug/local/random.txt"; //本地文件门路 String remoteFile = "/home/zimug/remote/targetfile.txt"; //上传到近程的文件门路,要保障登录用户有写权限 Session jschSession = null; try { JSch jsch = new JSch(); jsch.setKnownHosts("/home/zimug/.ssh/known_hosts"); jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT); // 通过ssh私钥的形式登录认证 // jsch.addIdentity("/home/zimug/.ssh/id_rsa"); // 通过明码的形式登录认证 jschSession.setPassword(PASSWORD); jschSession.connect(SESSION_TIMEOUT); Channel sftp = jschSession.openChannel("sftp"); //建设sftp文件传输管道 sftp.connect(CHANNEL_TIMEOUT); ChannelSftp channelSftp = (ChannelSftp) sftp; // 传输本地文件到近程主机 channelSftp.put(localFile, remoteFile); channelSftp.exit(); } catch (JSchException | SftpException e) { e.printStackTrace(); } finally { if (jschSession != null) { jschSession.disconnect(); } } System.out.println("文件传输实现!"); }}3. JSch异样解决在文件上传的过程中,咱们可能会遇到上面的一些异样 ...

October 12, 2020 · 1 min · jiezi

关于spring:前端面试每日-31-第545天

明天的知识点 (2020.10.12) —— 第545天 (我也要出题)[html] 应用div+css进行布局有什么益处?[css] 请形容一下网页的层叠等级(z-index)?[js] 写一个办法将UTC工夫和北京工夫换算[软技能] svn仓库的提交记录能迁徙到git吗?如何迁徙?《论语》,曾子曰:“吾日三省吾身”(我每天屡次检查本人)。前端面试每日3+1题,以面试题来驱动学习,每天提高一点!让致力成为一种习惯,让奋斗成为一种享受!置信 保持 的力量!!!欢送在 Issues 和敌人们一起探讨学习! 我的项目地址:前端面试每日3+1【举荐】欢送跟 jsliang 一起折腾前端,零碎整顿前端常识,目前正在折腾 LeetCode,打算买通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢送大家前来探讨,如果感觉对你的学习有肯定的帮忙,欢送点个Star, 同时欢送微信扫码关注 前端剑解 公众号,并退出 “前端学习每日3+1” 微信群互相交换(点击公众号的菜单:交换)。 学习不打烊,充电加油只为遇到更好的本人,365天无节假日,每天早上5点纯手工公布面试题(死磕本人,愉悦大家)。心愿大家在这虚夸的前端圈里,放弃沉着,保持每天花20分钟来学习与思考。在这变幻无穷,类库层出不穷的前端,倡议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢送大家到Issues交换,激励PR,感激Star,大家有啥好的倡议能够加我微信一起交换探讨!心愿大家每日去学习与思考,这才达到来这里的目标!!!(不要为了谁而来,要为本人而来!)交换探讨欢送大家前来探讨,如果感觉对你的学习有肯定的帮忙,欢送点个[Star]

October 12, 2020 · 1 min · jiezi

关于spring:Spring的BeanFactory是什么

什么是BeanFactory?提到Spring,总是让人第一工夫想起IOC容器,而IOC容器的顶层外围接口就是咱们的BeanFactory,如果可能了解BeanFactory的体系结构想必能让咱们对Spring整体脉络有更加清晰的认知,所以,本文的探索方向次要为以下几点: BeanFactory的体系结构是怎么的?Bean的元信息从何而来?BeanFactory生产Bean的过程是怎么的? BeanFactory的体系结构咱们先来看看有哪些子类实现了它吧 其中ApplicationContext这一块已在上篇文章有具体阐明,而DefaultListableBeanFactory这个底层实现类便天经地义的成为了咱们此次探索的出发点,为了让咱们有个更好的观感,以下是纯正的BeanFactoryUML图: 咱们能够看到DefaultListableBeanFactory实现的接口有: SingletonBeanRegistry: 定义了对单例缓存池相干的操作,如将bean注册到单例缓存池中ConfigurableBeanFactory: 可配置的BeanFactory,定义了各种各样的配置能力,如bean的作用域,bean的classLoader,增加bean的后置处理器,设置bean的创立状态,销毁bean等等AutowireCapableBeanFactory: 能进行主动拆卸的BeanFactory,这可能是咱们最为相熟的BeanFactory,定义了主动拆卸的类型(byName/byType),createBean, autowireBean, 主动拆卸属性, populateBean, initializeBean, 对于与bean生命周期相干的办法都将在这里体现ListableBeanFactory: 对BeanFactory的加强,定义了一系列依据beanType获取bean或者beanName的办法ConfigurableListableBeanFactory: 对ConfigurableBeanFactory的加强,定义了疏忽bean的类型、缓存bean定义、预实例化单例bean等办法BeanDefinitionRegistry: bean定义注册器,定义了与bean定义相干的办法如果说以上的接口体现了DefaultListableBeanFactory具备的性能,那么它所继承的一系列类就是这些性能的实现: DefaultSingletonBeanRegistry: 单例bean注册器,定义了三级缓存,其实就是三个Map属性FactoryBeanRegistrySupport: 提供对FactoryBean的反对AbstractBeanFactory: 实现了一系列操作IOC容器的性能,但最终的createBean仍旧交由子类AbstractAutowireCapableBeanFactory实现AbstractAutowireCapableBeanFactory: 实现了创立bean的性能,所有与创立bean的相干的性能都在这里DefaultListableBeanFactory: 在以上父类的性能根底上实现了ConfigurableBeanFactory和BeanDefinitionRegistry接口,定义了一些寄存Bean定义相干信息的Map看到这里,想必对DefaultListableBeanFactory曾经有一个大抵的理解了,那么问题来啦,咱们应该怎么从容器中获取一个bean呢?是不是只有通过BeanDefinitionRegistry注册一个bean定义,再通过AutowireCapableBeanFactory去createBean就实现了呢?就像上面这样:DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();RootBeanDefinition beanDefinition = new RootBeanDefinition(Wheel.class);beanFactory.registerBeanDefinition("wheel",beanDefinition);beanFactory.getBean("wheel", Wheel.class);Bean的元信息从何而来?咱们当初曾经晓得DefaultListableBeanFactory的大抵性能了,咱们发现当咱们想要创立一个Bean的时候,总是离不开一个名词:Bean定义,那么这个Bean定义到底是什么呢? BeanDefinition其实是一个接口,并不是一个具体的类,咱们也能够看一下它的UML图: 能够发现这里应用了模板办法的设计模式扩大了许多的子类,其中咱们最罕用的为RootBeanDefinition,它次要蕴含的属性如下: 咱们向容器中注册的Bean定义的信息大略就是如此,当BeanFactory生产Bean时,便能够通过beanClass分明的晓得Bean的类是什么,作用域是怎么,是否懒加载,init办法是什么等等等等 咦,如果一个最简略的bean,如同能够间接通过反射就搞定了耶~具体构造曾经分明了,那咱们来看一下注册过程吧 先从Demo看起public static void main(String[] args) { //创立一个DefaultListableBeanFactory实例 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //创立一个BeanDefinition RootBeanDefinition beanDefinition = new RootBeanDefinition(Wheel.class); //将BeanDefinition注册到容器中 beanFactory.registerBeanDefinition("wheel",beanDefinition);}public static class Wheel {}创立BeanDefinitionpublic RootBeanDefinition(@Nullable Class<?> beanClass) { //初始化父类 super(); //将beanClass赋值给this.BeanClass setBeanClass(beanClass);}初始化父类 ...

October 10, 2020 · 2 min · jiezi

关于spring:js日志输出还是只会consolelog么那你就out了

简直所有的javascript开发者最常应用的日志打印调试api都是console.log(),其实还有很多的选项供咱们抉择,笔者上面就为大家一一介绍. 一、console.table()console.table()是我十分倡议大家去应用的办法,它能够承受JSON或数组并以表格格局打印,在对json对象和数组进行可视化打印的时候简略易用,后果直观。 比方上面的json数据对象应用console.table()打印 console.table({ "id":"1", "key":"value", "count":2 });控制台的输入后果如下: 又比方对上面代码中的数组进行打印: console.table([ { id: "1", key: "value", count: 2, }, { id: "2", key: "value2", count: 22, }, { id: "3", key: "value3", count: 5, }, ]);控制台的输入后果如下: 二、console.error()console.error()绝对于console.log()更有助于在调试时从输入日志中辨别错误信息 从上图中能够看到,它的输入打印后果是红色的。 三、Time(time,timeLog,timeEnd)console.time()、console.timeLog()、console.timeEnd() 这三个办法当咱们对程序运行工夫进行计时的时候特地有用。 参考下图了解这三个办法 console.time()相当于秒表中的开始按钮console.timeLog()相当于秒表中的按圈计时/按点计时console.timeEnd()相当于计时完结console.time("ForLoop"); // "ForLoop" is label herefor (let i = 0; i < 5; i++) { console.timeLog('ForLoop'); }console.timeEnd("ForLoop");控制台打印输出后果 四、console.warn()用黄色字体输入日志,更直观的不便的查看正告类日志信息。 ...

October 10, 2020 · 1 min · jiezi

关于spring:手写一个类SpringBoot的HTTP框架几十行代码基于Netty搭建一个-HTTP-Server

本文曾经收录进 : https://github.com/Snailclimb/netty-practical-tutorial (Netty 从入门到实战:手写 HTTP Server+RPC 框架)。相干我的项目:https://github.com/Snailclimb/jsoncat (仿 Spring Boot 但不同于 Spring Boot 的一个轻量级的 HTTP 框架)目前正在写的一个叫做 jsoncat 的轻量级 HTTP 框架内置的 HTTP 服务器是我本人基于 Netty 写的,所有的外围代码加起来不过就几十行。这得益于 Netty 提供的各种开箱即用的组件,为咱们节俭了太多事件。 这篇文章我会手把手带着小伙伴们实现一个繁难的 HTTP Server。 如果文章有任何须要改善和欠缺的中央,欢送在评论区指出,共同进步! 开始之前为了防止有小伙伴不理解 Netty ,还是先来简略介绍它! 什么是 Netty?简略用 3 点来概括一下 Netty 吧! Netty 是一个基于 NIO 的 client-server(客户端服务器)框架,应用它能够疾速简略地开发网络应用程序。Netty 极大地简化并优化了 TCP 和 UDP 套接字服务器等网络编程,并且性能以及安全性等很多方面都要更好。Netty 反对多种协定 如 FTP,SMTP,HTTP 以及各种二进制和基于文本的传统协定。本文所要写的 HTTP Server 就得益于 Netty 对 HTTP 协定(超文本传输协定)的反对。Netty 利用场景有哪些?凭借本人的理解,简略说一下吧!实践上来说,NIO 能够做的事件 ,应用 Netty 都能够做并且更好。 ...

October 8, 2020 · 6 min · jiezi