文档章节

Spring学习笔记(14)——SpEL

乐在克里特
 乐在克里特
发布于 2017/02/23 13:47
字数 3765
阅读 1
收藏 0
点赞 0
评论 0
是什么
Spring表达式语言全称为“Spring Expression Language”,缩写为“SpEL”,类似于Struts2x中使用的OGNL表达式语言,能在运行时构建复杂表达式、存取对象图属性、对象方法调用等等,并能与Spring功能完美整合。
表达式语言给静态Java语言增加了动态功能。
SpEL是单独模块,只依赖于core模块,不依赖于其他模块,可单独使用。
 
能干什么
表达式语言一般是用较为简单的形式完成主要的工作,减少开发的工作量。
 
SpEL支持如下表达式:
一、基本表达式:字面量表达式、关系,逻辑与算数运算表达式、字符串连接及截取表达式、三目运算及Elivis表达式、正则表达式、括号优先级表达式;
二、类相关表达式:类类型表达式、类实例化、instanceof表达式、变量定义及引用、赋值表达式、自定义函数、对象属性存取及安全导航表达式、对象方法调用、Bean引用;
三、集合相关表达式:内联List、内联数组、集合,字典访问、列表,字典,数组修改、集合投影、集合选择;不支持多维内联数组初始化;不支持内联字典定义;
四、其他表达式:模板表达式。
 
在Java中使用SpringEL是非常简单的,示例如下:

java代码:
  1. public class HelloWorld {  
  2. public static void main(String[] args) {  
  3. //构造上下文:准备比如变量定义等等表达式运行需要的上下文数据  
  4. EvaluationContext context = new StandardEvaluationContext();  
  5. //创建解析器:提供SpelExpressionParser默认实现  
  6. ExpressionParser parser = new SpelExpressionParser();  
  7. //解析表达式:使用ExpressionParser来解析表达式为相应的Expression对象  
  8. Expression expression =  
  9. parser.parseExpression("('Hello' + ' World').concat(#end)");  
  10.    
  11. //设置上下文中的变量的值  
  12. context.setVariable("end""!SpringEL");  
  13. //执行表达式,获取运行结果  
  14. String str = (String)expression.getValue(context);  
  15. System.out.println("the str="+str);  
  16. }  
  17. }  
ExpressionParser接口
表示解析器,默认实现是org.springframework.expression.spel.standard包中的SpelExpressionParser类,使用parseExpression方法将字符串表达式转换为Expression对象。
配合   ExpressionParser  接口使用的ParserContext接口用于定义字符串表达式是不是模板,及模板开始与结束字符,示例如下:

java代码:
  1. public static void main(String[] args) {  
  2.  ExpressionParser parser = new SpelExpressionParser();  
  3.  //自定义一个解析模板的规则  
  4.     ParserContext parserContext = new ParserContext() {  
  5.         public boolean isTemplate() {             return true;        }  
  6.         public String getExpressionPrefix() {     return "#{";        }  
  7.         public String getExpressionSuffix() {     return "}";        }  
  8.     };  
  9.     String template = "#{'Hello '}#{'World!'}";  
  10.     Expression expression = parser.parseExpression(template, parserContext);  
  11.     System.out.println( expression.getValue());  
  12. }  
说明
1:在此演示的是使用ParserContext的情况,此处定义了ParserContext实现:定义表达式是模块,表达式前缀为“#{”,后缀为“}”;
2:使用parseExpression解析时传入的模板必须以“#{”开头,以“}”结尾,如“#{‘Hello ’}#{‘World!’}”。
3:请注意默认传入的字符串表达式不是模板形式,如之前演示的Hello World。
 
Expression接口
表示表达式对象,默认实现是org.springframework.expression.spel.standard包中的SpelExpression,提供getValue方法用于获取表达式值,提供setValue方法用于设置对象值
 
EvaluationContext接口
表示上下文环境,默认实现是org.springframework.expression.spel.support包中的StandardEvaluationContext类,使用setRootObject方法来设置根对象,使用setVariable方法来注册自定义变量,使用registerFunction来注册自定义函数等等。
 
字面量表达式:
 SpEL支持的字面量包括:字符串、数字类型(int、long、float、double)、布尔类型、null类型 ,示例如下:

java代码:
  1. 1:String str1 = parser.parseExpression("'Hello World!'").getValue(String.class);  
  2. 2:String str2 = parser.parseExpression("\"Hello World!\"").getValue(String.class);  
  3. 3int int1 = parser.parseExpression("1").getValue(Integer.class);  
  4. 4float float1 = parser.parseExpression("1.1").getValue(Float.class);  
  5. 5boolean true1 = parser.parseExpression("true").getValue(boolean.class);  
  6. 6:Object null1 = parser.parseExpression("null").getValue(Object.class);  
  7.    
算数运算表达式  
SpEL支持加(+)、减(-)、乘(*)、除(/)、求余(%)、幂(^)运算,示例如下:
1:int result1 = parser.parseExpression("1+2-3*4/2").getValue(Integer.class);
2:int result2 = parser.parseExpression(“4%3”).getValue(Integer.class) ;
3:int result3 = parser.parseExpression("2^3").getValue(Integer.class);
SpEL还提供求余(MOD)和除(DIV)运算符,与“%”和“/”等价,不区分大小写。
 
关系表达式
等于(==)、不等于(!=)、大于(>)、大于等于(>=)、小于(<)、小于等于(<=),区间(between)运算,示例如下:
1:“parser.parseExpression(”1>2“).getValue(boolean.class);”将返回false;
2:“parser.parseExpression(”1 between {1, 2}“).getValue(boolean.class);”将返回true。
SpEL同样提供了等价的“EQ” 、“NE”、 “GT”、“GE”、 “LT” 、“LE”来表示等于、不等于、大于、大于等于、小于、小于等于,不区分大小写
 
逻辑表达式:且(and)、或(or)、非(!或NOT)。 示例如下
1:String expression1 = "2>1 and (!true or !false)";
boolean result1 = parser.parseExpression(expression1).getValue(boolean.class);
注意:逻辑运算符不支持 Java中的 && 和 ||
 
字符串连接及截取表达式
使用“+”进行字符串连接,使用“‘String’ [index]”来获取一个字符,目前只支持获取一个字符,如“'Hello ' + 'World!'”得到“Hello World!”;而“'Hello World!'[0]”将返回“H”
 
三目运算及Elivis运算表达式
1:三目运算符 “表达式1?表达式2:表达式3”用于构造三目运算表达式,如“2>1?true:false”将返回true;
2:Elivis运算符“表达式1?:表达式2”从Groovy语言引入,用于简化三目运算符的,当表达式1为非null时则返回表达式1,当表达式1为null时则返回表达式2,如“null?:false”将返回false,而“true?:false”将返回true;
 
正则表达式
使用“str matches regex,如“‘123’ matches ‘\\d{3}’”将返回true;
 
括号优先级表达式
使用“(表达式)”构造,括号里的具有高优先级。
类类型表达式
使用“T(Type)”来表示java.lang.Class实例,“Type”必须是类全限定名,“java.lang”包除外,即该包下的类可以不指定包名;使用类类型表达式还可以进行访问类静态方法及类静态字段。 示例如下:
1:访问java.lang包的类
Class<String> result1 = parser.parseExpression("T(String)").getValue(Class.class);
2:访问其他包下的类 :
String expression2 = "T(cn.javass.spring.chapter5.SpELTest)";
    Class<String> result2 = parser.parseExpression(expression2).getValue(Class.class);
3:访问类的静态字段
int result3=parser.parseExpression("T(Integer).MAX_VALUE").getValue(int.class);
4:访问类的静态方法
int result4 = parser.parseExpression("T(Integer).parseInt('1')").getValue(int.class);
类实例化
类实例化同样使用java关键字“new”,类名必须是全限定名,但java.lang包内的类型除外,如String、Integer。示例如下:
1:String result1 = parser.parseExpression("new String('hello')").getValue(String.class);
2:Date result2 = parser.parseExpression("new java.util.Date()").getValue(Date.class);
 
instanceof表达式
SpEL支持instanceof运算符,跟Java内使用同义;如“hello‘ instanceof T(String)”将返回true。
 
变量定义及引用
1:变量通过EvaluationContext接口的setVariable(variableName, value)方法定义
2:在表达式中使用“#variableName”引用;
3:除了引用自定义变量,SpE还允许引用根对象及当前上下文对象,使用“#root”引用根对象,使用“#this”引用当前上下文对象;
示例如下:

java代码:
  1. ExpressionParser parser = new SpelExpressionParser();  
  2. EvaluationContext context = new StandardEvaluationContext();  
  3. context.setVariable("variable""hello1");  
  4. context.setVariable("variable""hello2");  
  5. String result1 = parser.parseExpression("#variable").getValue(context, String.class);  
  6. System.out.println("r1=="+result1);  
  7.    
  8. context = new StandardEvaluationContext(12);  
  9. String result2 = parser.parseExpression("#root-1").getValue(context, String.class);  
  10. System.out.println("r2=="+result2);  
  11. String result3 = parser.parseExpression("#this").getValue(context, String.class);  
  12. System.out.println("r3=="+result3);  
  13.    
输出结果:
r1==hello2
r2==11
r3==12
自定义函数
目前只支持类静态方法注册为自定义函数;SpEL使用StandardEvaluationContext的registerFunction方法进行注册自定义函数,其实完全可以使用setVariable代替,两者其本质是一样的。示例如下:

java代码:
  1. ExpressionParser parser = new SpelExpressionParser();  
  2. StandardEvaluationContext context = new StandardEvaluationContext();  
  3. Method parseInt =  
  4.        Integer.class.getDeclaredMethod("parseInt", String.class);  
  5. context.registerFunction("regParseInt", parseInt);  
  6. context.setVariable("parseInt2", parseInt);  
  7. String expression1 = "#regParseInt('3') == #parseInt2('3')";  
  8. boolean result =  
  9.     parser.parseExpression(expression1).getValue(context, boolean.class);  
  10. System.out.println("result="+result);  
可以看出“registerFunction”和“setVariable”都可以注册自定义函数,但是两个方法的含义不一样,推荐使用“registerFunction”方法注册自定义函数。
赋值表达式
SpEL即允许给自定义变量赋值,也允许给跟对象赋值,直接使用“#variableName=value”即可赋值。示例如下:

java代码:
  1. 1:parser.parseExpression("#root=‘Hi'").getValue(context, String.class);  
  2. 2:parser.parseExpression("#this=‘Hi'").getValue(context, String.class);  
  3. 3:context.setVariable("#variable""variable");  
  4.    
对象属性存取及安全导航表达式
对象属性获取非常简单,使用如“a.property.property”这种点缀式获取,SpEL对于属性名首字母是不区分大小写的;
SpEL还引入了Groovy语言中的安全导航运算符“(对象|属性)?.属性”,用来避免当“?.”前边的表达式为null时抛出空指针异常,而是返回null;
修改属性值可以通过赋值表达式或Expression接口的setValue方法修改。
示例如下:

java代码:
  1. UserModel um = new UserModel();  
  2. um.setUuid("User1");  
  3. um.setName("UserName1");  
  4. ExpressionParser parser = new SpelExpressionParser();  
  5. StandardEvaluationContext context = new StandardEvaluationContext();  
  6. context.setVariable("um",um);  
  7. //取值  
  8. Expression expression = parser.parseExpression("'uuid='+#um.uuid + ',name='+#um.name");  
  9. String v =  expression.getValue(context,String.class);  
  10. System.out.println("v=="+v);  
  11. //赋值  
  12. expression = parser.parseExpression("'uuid='+(#um.uuid='newUser') + ',name='+#um.name");  
  13. v =  expression.getValue(context,String.class);  
  14. System.out.println("v2=="+v);  
  15. 输出结果:  
  16. v==uuid=User1,name=UserName1  
  17. v2==uuid=newUser,name=UserName1  
对象方法调用
对象方法调用更简单,跟Java语法一样;如“‘Hello’.substring(1,3)”将返回“el”;而对于根对象可以直接调用方法。
Bean引用
SpEL支持使用“@”符号来引用Bean,在引用Bean时需要使用BeanResolver接口实现来查找Bean,Spring提供BeanFactoryResolver实现,示例如下:

java代码:
  1. ApplicationContext ctx = new ClassPathXmlApplicationContext(  
  2.         new String[] {"applicationContext.xml"});  
  3.    
  4. ExpressionParser parser = new SpelExpressionParser();  
  5. StandardEvaluationContext context = new StandardEvaluationContext();  
  6. context.setBeanResolver(new BeanFactoryResolver(ctx));  
  7. String result1 =  
  8. parser.parseExpression("@myBean.test()").getValue(context, String.class);  
内联List
从Spring3.0.4开始支持内联List,使用{表达式,……}定义内联List,如“{1,2,3}”将返回一个整型的ArrayList,而“{}”将返回空的List,对于字面量表达式列表,SpEL会使用java.util.Collections.unmodifiableList方法将列表设置为不可修改。示例如下:
1://将返回不可修改的空List
List<Integer> result2 = parser.parseExpression("{}").getValue(List.class);
2:对于字面量列表也将返回不可修改的List
ExpressionParser parser =   new  SpelExpressionParser();
List<Integer> result1 = parser.parseExpression("{1,2,3}").getValue(List.   class);
//result1.set(0, 2);//这句话会报错,因为list不可以修改
System.   out.println(result1);
3://对于列表中只要有一个不是字面量表达式,将只返回原始List,
//不会进行不可修改处理,也就是可以修改
String expression3 = "{{1+2,2+4},{3,4+4}}";
List<List<Integer>> result3 = parser.parseExpression(expression3).getValue(List.class);
result3.get(0).set(0, 1);
内联数组
和Java 数组定义类似,只是在定义时进行多维数组初始化。 示例如下:
1://定义一维数组并初始化
int[] result1 = parser.parseExpression("new int[1]").getValue(int[].class);
2://声明二维数组并初始化
int[] result2 = parser.parseExpression("new int[2]{1,2}").getValue(int[].class);
3://定义多维数组但不初始化
int[][][] result3 = parser.parseExpression(expression3).getValue(int[][][].class);
4://错误的定义多维数组,多维数组不能初始化
String expression4 = "new int[1][2][3]{{1}{2}{3}}";
int[][][] result4 = parser.parseExpression(expression4).getValue(int[][][].class);
访问元素
SpEL目前支持所有集合类型和字典类型的元素访问,使用“集合[索引]”访问集合元素,使用“map[key]”访问字典元素 。示例如下;
1://SpEL内联List访问
int result1 = parser.parseExpression("{1,2,3}[0]").getValue(int.class);
//相当于result1.get(0)
 
2://SpEL目前支持所有集合类型的访问
Collection<Integer> collection = new HashSet<Integer>();
collection.add(1);
collection.add(2);
EvaluationContext context2 = new StandardEvaluationContext();
context2.setVariable("collection", collection);
int result2 = parser.parseExpression("#collection[1]").getValue(context2, int.class);
3://SpEL对Map字典元素访问的支持
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
EvaluationContext context3 = new StandardEvaluationContext();
context3.setVariable("map", map);
int result3 = parser.parseExpression("#map['a']").getValue(context3, int.class);
 
元素修改
可以使用赋值表达式或Expression接口的setValue方法修改。示例如下:
1://修改数组元素值
int[] array = new int[] {1, 2};
EvaluationContext context1 = new StandardEvaluationContext();
context1.setVariable("array", array);
int result1 = parser.parseExpression("#array[1] = 3").getValue(context1, int.class);
2://修改集合值
Collection<Integer> collection = new ArrayList<Integer>();
collection.add(1);
collection.add(2);
EvaluationContext context2 = new StandardEvaluationContext();
context2.setVariable("collection", collection);
int result2 = parser.parseExpression("#collection[1] = 3").getValue(context2, int.class);
parser.parseExpression("#collection[1]").setValue(context2, 4);
result2 = parser.parseExpression("#collection[1]").getValue(context2, int.class);
3://修改map元素值
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
EvaluationContext context3 = new StandardEvaluationContext();
context3.setVariable("map", map);
int result3 = parser.parseExpression("#map['a'] = 2").getValue(context3, int.class);
集合投影
在SQL中投影指从表中选择出列,而在SpEL指从集合中的元素,通过选择来构造新的集合,该集合和原集合具有相同数量的元素,但可能属性不一样;SpEL使用“(list|map).![投影表达式]”来进行投影运算。
1:示例集合的投影
//1.首先准备测试数据
Collection<UserModel> collection = new ArrayList<UserModel>();
UserModel um1 = new UserModel();
um1.setUuid("u1");
um1.setName("u1Name");
collection.add(um1);
UserModel um2 = new UserModel();
um2.setUuid("u2");
um2.setName("u2Name");
collection.add(um2);
//2.测试集合或数组
EvaluationContext context1 = new StandardEvaluationContext();
ExpressionParser parser = new SpelExpressionParser();
context1.setVariable("collection", collection);
Collection<String> result1 =
parser.parseExpression("   #collection.![#this.name]").getValue(context1, Collection.class);
SpEL投影运算还支持Map投影,但Map投影最终只能得到List结果,对于投影表达式中的“#this”将是Map.Entry,所以可以使用“value”来获取值,使用“key”来获取键。 示例如下:
//1.首先准备测试数据

java代码:
  1. UserModel um1 = new UserModel();  
  2. um1.setUuid("u1");  
  3. um1.setName("u1Name");  
  4. UserModel um2 = new UserModel();  
  5. um2.setUuid("u2");  
  6. um2.setName("u2Name");  
  7. Map<String, UserModel> map = new HashMap<String, UserModel>();  
  8. map.put(um1.getUuid(),um1);     
  9. map.put(um2.getUuid(),um2);  
  10. //2.测试Map投影  
  11. EvaluationContext context1 = new StandardEvaluationContext();  
  12. ExpressionParser parser = new SpelExpressionParser();  
  13. context1.setVariable("map", map);  
  14. Collection<String> result1 =  
  15. parser.parseExpression("#map.![#this.value.name]").getValue(context1, Collection.class);  
集合筛选
在SpEL指根据原集合通过条件表达式选择出满足条件的元素并构造为新的集合,SpEL使用“(list|map).?[选择表达式]”,其中选择表达式结果必须是boolean类型,如果true则选择的元素将添加到新集合中,false将不添加到新集合中。示例如下:
//1:准备测试数据的过程跟上一个示例一样,就不重复了
//2.测试集合或数组的筛选

java代码:
  1. EvaluationContext context1 = new StandardEvaluationContext();  
  2. ExpressionParser parser = new SpelExpressionParser();  
  3. context1.setVariable("collection", collection);  
  4. Collection<String> result1 =  
  5. parser.parseExpression("#collection.?[#this.uuid.equals('u1')]").getValue(context1, Collection.class);  
  6.    
//测试Map筛选

java代码:
  1. EvaluationContext context1 = new StandardEvaluationContext();  
  2. ExpressionParser parser = new SpelExpressionParser();  
  3. context1.setVariable("map", map);  
  4. Map<String,UserModel> result1 =  
  5. parser.parseExpression("#map.?[#this.key=='u1']").getValue(context1, Map.class);  
nXml风格的配置
SpEL支持在Bean定义时使用,默认使用“#{SpEL表达式}”表示,不允许嵌套。其中“#root”根对象默认可以认为是ApplicationContext,获取根对象属性其实是获取容器中的Bean。
nXml风格的配置示例----通过SpEL表达式设置值

java代码:
  1. <bean id="numberGuess" class="org.spring.samples.NumberGuess">  
  2. <property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>  
  3. </bean>  
Xml风格的配置示例----通过SpEL表达式参照其他的Bean

java代码:
  1. <bean id="t1" class="cn.javass.spring3.hello.T2">  
  2.     <property name="value" value="#{ T(java.lang.Math).random() * 100.0 }"/>  
  3. </bean>  
  4. <bean id="t2" class="cn.javass.spring3.hello.T2">  
  5.     <property name="value" value="#{ T(Double).parseDouble(t1.value) -1 }"></property>  
  6. </bean>  
上面的t1就会被解析成为参照t1这个Bean,当然也可以使用@t1来表示。
注解风格的配置
使用@Value注解来指定SpEL表达式,该注解可以放到字段、方法及方法参数上。 但是要在配置文件中使用<context:annotation-config/> 来开启对注解的支持。示例如下:

java代码:
  1. public class SpELBean {  
  2.     @Value ("#{ T(java.lang.Math).random() * 100.0 }")  
  3.     private String value;  
  4.     //setter和getter由于篇幅省略,自己写上  
  5. }  
注意:如果同时使用了@Value和setter注入,那么setter注入将覆盖@Value的值。
 

© 著作权归作者所有

共有 人打赏支持
乐在克里特
粉丝 15
博文 268
码字总数 394729
作品 0
杭州
程序员
Spring.NET学习笔记——目录(原)

目录 前言 Spring.NET学习笔记——前言 第一阶段:控制反转与依赖注入IoC&DI Spring.NET学习笔记1——控制反转(基础篇) Level 200 Spring.NET学习笔记2——环境搭建(基础篇) Level 200 Sprin...

长平狐
2012/06/11
887
1
让Spring Security 来保护你的Spring Boot项目吧

参考资料: 书籍:Spring实战(第4版) 第9章和第14章 Spring Security 参考手册 初识 Spring Security 程序猿DD的Spring Security学习笔记 Spring Security 简介 Spring Security是一个能够为...

潇潇漓燃
05/19
0
0
Spring Bean定义中表达式语言的支持

SpEL(Spring Expression Language,Spring表达式语言)的一个重要的作用就是扩展Spring容器的功能,允许在Bean定义中使用SpEL。XML配置文件和Annotation中都可以使用SpEL。在XML和Annotatio...

摆渡者
2014/03/09
0
0
Spring表达式语言:SpEL(三)

本文为转载学习 原文链接:http://jinnianshilongnian.iteye.com/blog/1418311 5.4.1 xml风格的配置 SpEL支持在Bean定义时注入,默认使用“#{SpEL表达式}”表示,其中“#root”根对象默认可以...

heroShane
2014/02/02
0
0
Spring HTTP Invoker 学习小记

Spring HTTP Invoker是spring框架中的一个远程调用模型,执行基于HTTP的远程调用,也就是说,可以通过防火墙,并使用java的序列化机制在网络间传递对象。客户端可以很轻松的像调用本地对象一...

felixlv
2013/04/05
0
5
安全的复杂之处:安全web请求的架构

借助于Spring Security的强大基础配置功能以及内置的认证功能,我们在前面讲述的三步配置是很快就能完成的;它们的使用是通过添加auto-config属性和http元素实现的。 但不幸的是,应用实现的...

bigYuan
2014/12/04
0
0
后台开发常问面试题集锦(问题搬运工,附链接)

Java基础问题 String的’+’的性能及原理 java之yield(),sleep(),wait()区别详解-备忘笔记 深入理解Java Stream流水线 抽象 & abstract关键字 Java final 修饰符知识点总结(必看篇) Java中的...

大黄有故事
2017/11/18
0
0
【原创】遨游springmvc之WebDataBinder

1.前言 先上原理图 在我们学习servlet的时候我们知道有一个方法叫做:request.getParameter("paramName"),它返回的是一个String类型,但是如果一切都是这样子我们开发程序的时候就会显得特别...

开源中国首席脑科主任
2016/08/02
471
1
springmvc+mybatis学习笔记(汇总)

springmvc+mybatis学习笔记(汇总) 标签 : springmvc mybaits [TOC] 笔记分为两大部分:mybatis和springmvc mybatis springmvc 笔记内容主要是mybatis和springmvc的一些基本概念和使用方法,...

brianway
2016/03/30
1K
2
网关 Spring-Cloud-Gateway 源码解析 —— 网关初始化

网关 Spring-Cloud-Gateway 源码解析 —— 网关初始化 Harries Blog™2017-12-135 阅读 SpringAppclasspathcatbeanAPIbuildbug 本文主要基于 Spring-Cloud-Gateway 2.0.X M4 摘要: 原创出处 ......

Harries Blog™
2017/12/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

虚拟机怎么安装vmware tools

https://blog.csdn.net/tjcwt2011/article/details/72638977

AndyZhouX
12分钟前
0
0
There is no session with id[xxx]

参考网页 https://blog.csdn.net/caimengyuan/article/details/52526765 报错 2018-07-19 23:04:35,330 [http-nio-1008-exec-8] DEBUG [org.apache.shiro.web.servlet.SimpleCookie] - Found......

karma123
13分钟前
0
0
vue-router懒加载

1. vue-router懒加载定义 当路由被访问的时候才加载对应组件 2. vue-router懒加载作用 当构建的项目比较大的时候,懒加载可以分割代码块,提高页面的初始加载效率。 ###3. vue-router懒加载实...

不负好时光
20分钟前
0
0
庆祝法国队夺冠:用Python放一场烟花秀

天天敲代码的朋友,有没有想过代码也可以变得很酷炫又浪漫?今天就教大家用Python模拟出绽放的烟花庆祝昨晚法国队夺冠,工作之余也可以随时让程序为自己放一场烟花秀。 这个有趣的小项目并不...

猫咪编程
22分钟前
0
0
SpringBoot | 第七章:过滤器、监听器、拦截器

前言 在实际开发过程中,经常会碰见一些比如系统启动初始化信息、统计在线人数、在线用户数、过滤敏高词汇、访问权限控制(URL级别)等业务需求。这些对于业务来说一般上是无关的,业务方是无需...

oKong
35分钟前
5
0
存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储

存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储 存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储。 顺序结构和链接结构适用在内存结构中。 顺序表每个单元都是按物理...

DannyCoder
46分钟前
1
0
Firefox 61已经为Ubuntu 提供支持

最新和最好的Mozilla Firefox 61 “Quantum”网络浏览器已经为Ubuntu Linux操作系统的用户提供了支持,现在可以通过官方软件库进行更新。 Mozilla于2018年6月26日发布了Firefox 61版本,该版...

六库科技
今天
0
0
Win10升级后执行系统封装(Sysprep)报错

开始封装 一年多以前开始给公司封装Win10系统,便于统一给公司电脑初始化携带各种软件的系统,致力于装完既可以开发的状态。那时候最新的版本是Win10 1703版本,自然就以他为母盘,然后结合V...

lyunweb
今天
40
0
php 性能优化

#什么情况下会遇到性能问题 PHP 语法使用的不恰当

to_be_better
今天
0
0
Jenkins 构建触发器操作详解

前言 跑自动化用例每次用手工点击jenkins出发自动化用例太麻烦了,我们希望能每天固定时间跑,这样就不用管了,坐等收测试报告结果就行。 一、定时构建语法 * * * * * (五颗星,中间用空格隔...

覃光林
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部