有时候我们操作linux,编辑一些系统文件时是需要sudo操作
的,但是经常忘记使用`sudo `,直接就是vim 打开某个文件,当进行改动时出现以下情况,就要退出,重新用sudo vim 打开文件操作。
我们如何在不退出的情况下完成编写呢?
输入`:w ! sudo tee %`, 回车,出现下面提示,按`o` 再`回车`就可以了。
最后强制退出`:q!`
最后用cat 输入内容检查下,就会发现刚刚的内容已经写入了。
`:w ! sudo tee %`的意思是
:w! {cmd} 让vim 可以执行外部shell命令{cmd},且把当前缓冲区的内容从stdin传入。
tee 是一个把stdin保存到文件里的小工具
% 会vim 里的特殊字符,保存着当前文件的路径
整个意思就是把当前是文件缓冲区的内容(也就是你修改的内容)做为stdin传给tee让它写入到当前文件里。
相信很多同学一直用的是`@Autowired`, 另外也都知道都能用,但是也不知道有啥子区别。看看下面的以后就不怕别人问你为什么用她而不用他了。
先说结论: 推荐用构造器方式,简单粗暴的原因是人家Spring在Spring4.x版本中推荐的写法。
@Autowired
这位兄弟是根据type装配哒。默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。而它是spring的产物.
---
@Resource
而这位老兄呢,是jdk的产物。是按name来装配的,但也可以通过type来装配。
@Resource装配顺序
如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
---
构造器
举个例子吧!
public class A {
private final Field field;
public A(Field field) {
this.field = field;
}
}
但我通常写都用结合`lombok`食用,更香点。不知道的同学查查是什么哟!
@AllArgsConstructor //看名字就知道什么意思,同上面例子一模一样,写法简洁一点
public class A {
private final Field field;
}
Spring 这么说了
> The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.
google翻译
> Spring团队通常提倡构造函数注入,因为它使人们能够将应用程序组件实现为不可变的对象并确保所需的依赖项不为null。此外,注入构造函数的组件总是以完全初始化的状态返回到客户端(调用)代码。
画重点
1. 不可变对象:所以为什么依赖对象前面要加个final
2. 确保依赖对象不为null: 不致于在正调用时才报错,直接启动就报错。
---
对于IOC容器以外的环境,除了使用反射来提供它需要的依赖之外,无法复用该实现类。而且将一直是个潜在的隐患,因为你不调用将一直无法发现NPE的存在。
另外,使用field注入可能会导致`循环依赖`。
如果使用构造器注入,在spring项目启动的时候,就以此告诉你的程序循环依赖。
会报The dependencies of some of the beans in the application context form a cycle
如果是field注入的话,启动的时候不会报错,在使用那个bean的时候才会报错。
新人报道吖~~,第一次在这里分享,希望对大家有帮助,一直成长!
今日分享AOP
我们在写 web 项目时,请求内容日志记录对我们来说很重要,特别是出问题的要排查时,传的什么参数,返回内容都是我们排查的依据,那我们不可能每个controller上的每一个方法都打印log,对原有业务代码有侵入性,代码也冗余和繁琐。此时AOP就起到了重要作用。可以对业务无任何侵入。而本文实现用的@Around,如单词意思是围绕,就是包围着业务代码。那我们就可以在业务执行前获取请求参数打印,执行完成着结果打印,就实现我们的功能了。
建一个LogTraceHandlerAop文件,随便找个地方放下就可以。把
@Around 改成你的目标目录即可
LogTraceHandlerAop.java
@Slf4j
@Aspect
public class LogTraceHandlerAop {
// controller 下的所有方法
@Around("execution(* com.example.demo.controller..*.*(..))")
public Object doAround(ProceedingJoinPoint call) throws Throwable {
MethodSignature signature = (MethodSignature) call.getSignature();
Object[] args = call.getArgs();
if (args.length <= 0) {
return call.proceed();
}
Method method = signature.getMethod();
String methodName = method.getName();
String[] classNameArray = method.getDeclaringClass().getName().split("\\.");
String className = classNameArray[classNameArray.length - 1];
StringBuilder buffer = new StringBuilder();
for (Object arg : args) {
buffer.append(" ");
buffer.append(arg);
}
log.info("请求方法:{},请求参数:{}", className + "." + methodName, buffer.toString());
// 主要业务
Object result = call.proceed();
// 返回结果
String resJson = JSON.toJSONString(result);
log.info("请求返回结果{}", resJson);
return result;
}
}