@andrewwang
2017-03-20T22:56:15.000000Z
字数 8438
阅读 1054
技术
Java
系统架构(船架)
业务隔离机制(船的防水隔离)
系统profile(体检)
约定大于配置(惯例优先原则)
所有操作都要有反馈。特别是API,一定要有返回码。
Order o = getOrder(id);
if (o is unpay) { // 提高性能的判断,只适用于单向状态图
try (Lock lock = lock(getLockName("Order", id))) {
o = getOrder(id);
if (o is unpay)
payOrder(id);
}
}
BigDecimal bd1 = new BigDecimal("1.00");
Assert.assertFalse(BigDecimal.ONE.equals(bd1));
Assert.assertTrue(BigDecimal.ONE.compareTo(bd1) == 0);
属性文件的属性spring.jpa.hibernate.ddl-auto
auto是创建,none是不创建
建议多用none,可以节省启动时间
@PostConstruct
private void init() {
}
@Value("${prop}") // 必须在属性文件设置
@Value("${prop:}") // 有默认值,如字符空
@Value("${prop:hello}") // 设置默认值是hello,属性文件优先
String prop = "hi"; // 赋值是无效的
@JsonSerialize(using = CustomDateTimeSerializer.class)
public Date getCreatetime() {}
@RequestBody User user
@RequestBody接收的对象定义规则,否则函数会异常(无法响应)
1. 必须要有默认构造函数
2. 如有子类,其在接收类的变量定义必须是static
也可以直接接收String,如@RequestBody String data
url路径参数:@PathVariable String entity
querystring参数:@RequestParam("data") String data
, @RequestParam int pageIndex, @RequestParam(defaultValue = "10") int pageSize
new PageImpl<Order>(pl, new PageRequest(pageIndex, pageSize), total)
Page<Source> sourcePage = null;
Page<Target> = sourcePage.map(new Converter<Source, Target>() {
@Override
public Target convert(Source source) {
return new Target(source);
}
});
JPA多表查询
@Query("SELECT t FROM CmsArticle t, CmsCategory u WHERE t.categoryId=u.id AND t.status=:status AND u.code=:code AND u.parentId is null AND u.status=:status")
public Page<CmsArticle> searchByCategory(@Param("code") String code, @Param("status") int status, Pageable pageable);
JPA单表/多表搜索,对象要有关联(不推荐本方案)
不需要定义key,key是有规则生成的。函数参数必须是Object类型
@Cacheable(value = "ProductListByCategory")
如果返回值是列表,则必须定义具体列表,如ArrayList,绝对不能使用List。
同一个类的函数调用是不能启用缓存的(即缓存无效)
字符串处理:分割,连接,填充
数组操作,含集合生成新集合
CharMatcher
URL的处理是通过语法@{...}来处理:
<a th:href="@{http://www.thymeleaf.org}">Thymeleaf</a>
字符串替换:
局部:<span th:text="|Welcome to our application, ${user.name}!|"> th:href="|mailto:${text_email}|"
全部:th:href="${jsFile}"
自定义属性:
<div th:attr="selfdefineAttr=${xxx}"></div>
等号不能括号起来
<div th:attr="style='background-image:url('+${banner.pic}+')'"></div>
等同于上面<div th:style="'background-image:url('+${banner.pic}+')'"></div>
直接显示html:
方式1:<div th:remove="tag" th:utext="${content}"></div>
方式2:<%==content%>,单个=是值,两个=是html显示
\w 匹配字母或数字或下划线或汉字 [a-zA-Z_0-9]
\s 匹配任意的空白符(空格、TAB\t、回车\r \n)
\d 匹配数字 [0-9]
^ 匹配字符串的开始
$ 匹配字符串的结束
http://blog.csdn.net/guolong1983811/article/details/51501346
库类型的jar包(非运行包),不要用spring-boot-maven-plugin
UnsupportedOperationException
log.info(LogUtils.gen("message", "key1", value1, "key2", value2));
log.info(LogUtils.gen("getUser", ImmutableMap.<String, String> builder().put("token", token).put("userId", userId).build()));
一般是从parent克隆出child
BeanUtils.copyProperties(parent, child);
this.getClass().isAnnotationPresent(BizApi.class); // 获取所有引用的判断:BizApi是annotation
this.service = this.context.getBean(IUserAccountService.class);
for (Map.Entry<String, Object> entry : this.context.getBeansWithAnnotation(BizApi.class).entrySet()) {
this.apiMap.put(entry.getKey(), (IBizApi) entry.getValue());
}
List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
Arrays.asList(new String[] { "13589878678", "13690378756" })
Joiner.on(",").join(list);
Map<String, String> map = this.getRequestParams(request);
String body = Joiner.on("&").withKeyValueSeparator("=").join(map);
final Map<String, String> join =Splitter.on("&").withKeyValueSeparator("=").split("id=123&name=green”);
Splitter. on("," ).omitEmptyStrings().splitToList("sd,dsf");
ImmutableMap.<String, String>builder().put("uri", uri).put("body", body).build();
####从一个list生成另外一个list(Advertise转换成ClientBanner)
Lists.transform(listAdv, new Function<Src, Target>() {
@Override
public Target apply(Src src) {
return new Target(src);
}
});
Map<String, Company> objMap = companyList.stream().collect(Collectors.toMap(Company::getCode, (obj) -> obj));
List<User> userList = Lists.newArrayList();
this.partyDao.findAll().forEach((party)->userList.add(new User(party)));
Map也可以同样循环处理
User obj;
// String jsonText = new Gson().toJson(obj);
String jsonText = JSONUtils.toJson(obj, User.class, false);
User user = JSONUtils.fromJsonObject(jsonObject, User.class, null);
// User user = new GsonBuilder().create().fromJson(jsonText, User.class);
User user = JSONUtils.fromJson(jsonText, User.class);
// 获取特定对象列表
List<Person> rtn =JSONUtils.fromJson(jsonText, new TypeToken<List<Person>>(){}.getType());
ArrayList<String> list = JSONUtils.fromJson(jsonText, ArrayList.class);
// 默认序列化有问题(map里的number会转成double)
// 获取对象列表,对象是个map,和json的对象值一一对应。
jsonText = "[{id:123,name:'第三方',price:8.88}]";
ArrayList<Map<String, Object>> list = JSONUtils.fromJson(jsonText, ArrayList.class, ArrayList.class, new ListMapJsonDeserializer());
Map<Integer,Person> map =JSONUtils.fromJson(jsonText, new TypeToken<Map<Integer,Person>>(){}.getType());
jsonText = "{id:123,name:'第三方',price:8.88}";
Map<String, Object> map = JSONUtils.fromJson(jsonText, HashMap.class, HashMap.class, new MapJsonDeserializer());
// com.fasterxml.jackson.databind
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(jsonText, Map.class);
JsonObject jo = JSONUtils.parse(jsonText);
JsonArray ja = JSONUtils.parseArray(jsonText);
JsonObject jo = new JsonObject();
jo.add("list", JSONUtils.toJsonElement(list));
jo.add("obj", JSONUtils.toJsonElement(obj));
jo.add("value", new JsonPrimitive(val));
new Thread(new Runnable() {
@Override
public void run() {
// code here
}
}
}).start();
public <T> void test(T t1) {} // 函数定义
test(new ClassA()); // 调用
public void callbackUsage(Function<String, String> fn) {
fn.apply(“123”);
}
this.callbackUsage(new Function<String, String>() {
@Override
public String apply(String t) {
return null;
}
});
@RunWith(SpringRunner.class)
@SpringBootTest
查看内存分配命令(可以看到大量占用内存的对象):jmap –histo:live [pid]
dump命令:jmap -dump:live,format=b,file=p.dump [pid]
外部工具
visualvm
Jstatd方式远程监控Linux下 JVM运行情况TODO
内置到项目
JavaMelody
Spring Boot集成TODO
业务层需将业务信息注入框架层。实现示例如下(框架层获取业务层的用户信息):
层级 | 类 | 说明 |
---|---|---|
框架层 | 实体类UserAccount | 框架层使用的用户信息结构 |
框架层 | 服务类UserAccountService | 框架层其他类获取用户信息的入口,实例化IUserAccountService就是注入 |
框架层 | 接口类IUserAccountService | |
业务层 | 服务类UserService,实现接口IUserAccountService | 继承接口就是定义注入类 |
使用说明
图片地址示例:http://qr.liantu.com/api.php?text=http://www.xyz.com/shop/1111
Dubbo:RPC+ZooKeeper
spring-wind:可参考代码和代码结构。
iBase4J:采用了ZooKeeper,分布式服务理念
Hasor-RSF:分布式服务框架
Redkale:有点大。第三方接入采用插件模式
eova:老了,可参考思想。
sharding-jdbc
告别手写 API文档生成工具推荐
阿里完整自动化测试解决方案 macaca