1. 说说你对Spring的理解
Spring是企业级引用开发的一个开源框架,他的核心主要包括IOC (Inversion of Control, 控制反转)和AOP (面向切面编程, 应用场景如事务,日志,通用异常捕获等),Spring全家桶可以满足绝大部分的开发组件。
全家桶包括
Spring Core (核心)
数据库 (JPA/JDBC/myBatis)
消息缓存中间件 (Kafka,Redis)
etc.
2. 说说你对Spring IOC的理解
IOC(Inversion of Control)即控制反转,所有Bean的生命周期(创建,初始化,销毁)管理交给Spring容器来管理,而不是由开发人员来控制(传统Java开发中是由开发人员主动写new方式去创建java对象),这就是反转控制(从开发者角度反转到由Spring容器去控制)。
这里会涉及到Spring的一个重要概念依赖注入(Dependency Injection), 依赖注入的方式有:
构造器注入
Setter方法注入
通过注解注入 @Autowire
3. 说说你对Spring AOP的理解
AOP的好处:切面编程可以把业务逻辑代码跟系统服务分离,developer只要专注于开发业务逻辑就可以了。
Spring AOP如何实现:
JDK动态代理通过反射来接收代理的类,但是被代理的类必须实现接口,核心是InvocationHandler和Proxy类
@Slf4j
public class UserServiceInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log.info("start method - {}", method.getName());
log.info("args - ");
for (Object o : args) {
log.info(o.toString());
}
Object res = method.invoke(target, args);
log.info("complete method - {}", method.getName());
return res;
}
public static void main(String[] args) {
UserServiceInvocationHandler handler = new UserServiceInvocationHandler();
handler.setTarget(new UserServiceImpl());
UserService userService = (UserService) handler.getProxy(); // JDK动态代理只能通过接口,所以这边只能强制转类型为对应的接口
userService.add(new User(UUID.randomUUID().toString(), "Weijie Chen", 36));
}
}
cglib动态代理的类一般是没有实现接口的类,cglib是一个代码生成类库,可以在运行时动态生成某个类的子类,所以,cglib是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用cglib来做动态代理的, 主要的CGLIB工具类有Enhancer, MethodInterceptor, MethodProxy
@Slf4j
public class CglibDynamicProxy implements MethodInterceptor {
public Object createProxy(Object target){
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(target.getClass()); // create parent class
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable {
log.info("before executing method - " + method.getName());
log.info("this is a tag before method executing...");
Object obj= proxy.invokeSuper(o, args);
log.info("this is a tag after method executing...");
log.info("after executing method - " + method.getName());
return obj;
}
}
@Slf4j
class CglibDynamicProxyTester {
public void test1() {
log.warn("method test1 is running.");
}
public void test2() {
log.warn("method test2 is running.");
}
public static void main(String[] args) {
// 创建代理类
CglibDynamicProxy proxy = new CglibDynamicProxy();
// 创建(需要被代理的)服务类
CglibDynamicProxyTester tester = new CglibDynamicProxyTester();
// 根据服务类创建被代理类的代理子类
CglibDynamicProxyTester proxyObj = (CglibDynamicProxyTester) proxy.createProxy(tester);
proxyObj.test1();
proxyObj.test2();
}
}