最全【Java从0到架构师】Spring - 生命周期、代理,华为4面技术5面HR

最后

看完美团、字节、腾讯这三家的面试问题,是不是感觉问的特别多,可能咱们又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。

开篇有提及我可是足足背下了1000道题目,多少还是有点用的呢,我看了下,上面这些问题大部分都能从我背的题里找到的,所以今天给大家分享一下互联网工程师必备的面试1000题

注意不论是我说的互联网面试1000题,还是后面提及的算法与数据结构、设计模式以及更多的Java学习笔记等,皆可分享给各位朋友

最新“美团+字节+腾讯”一二三面问题,挑战一下你能走到哪一面?

互联网工程师必备的面试1000题

而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题

最新“美团+字节+腾讯”一二三面问题,挑战一下你能走到哪一面?

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 在业务层加入附加代码会显得很臃肿、累赘

  • 但很多时候又好像不得不加


类比到生活中的一些问题可以更好的理解:

  • 房东只需要做自己必须要做的事情,其余事情交给中介(代理)去做

在这里插入图片描述

对于程序开发而言:

  • 业务层只需要处理好业务代码,其余的事情交给代理去做

在这里插入图片描述


代理的作用:在不修改目标类的目标方法代码的前提下,为目标方法增加额外功能

代理类中必须也有同样的目标方法

  • 代理类实现跟目标类同样的接口

  • 若目标类没有实现接口,代理类继承目标类

代理的实现方案:

  • 静态代理 (Static Proxy)

开发人员需要手动编写代理类(创建对应的 *.java 文件)

基本上,一个目标类就需要编写一个代理类

  • 动态代理 (Dynamic Proxy)程序运行过程中动态生成代理类的字节码

静态代理 (Static Proxy)


示例代码:静态代理

要代理 UserServiceImpl,需要实现 UserService 接口(或者继承目标类):

// 代理类实现跟目标类同样的接口

public class UserServiceProxy implements UserService {

private UserService target;

// 为基于setter的注入提供条件

public void setTarget(UserService target) {

this.target = target;

}

@Override

public boolean login(String username, String password) {

// 额外操作

System.out.println(“日志------------------1”);

// 调用目标类的方法实现

boolean result = target.login(username, password);

// 额外操作

System.out.println(“日志------------------2”);

return result;

}

}

// 代理类继承目标类, 也可实现静态代理

public class SkillServiceProxy extends SkillService {

private SkillService target;

public void setTarget(SkillService target) {

this.target = target;

}

@Override

public boolean save(Object skill) {

System.out.println(“SkillServiceProxy - 1”);

boolean result = target.save(skill);

System.out.println(“SkillServiceProxy - 2”);

return result;

}

}

<bean id=“userService”

class=“com.mj.proxy.UserServiceProxy”>

<bean id=“skillService”

class=“com.mj.proxy.SkillServiceProxy”>

动态代理 (Dynamic Proxy)


动态代理的常见实现方案有 2 种:

  1. JDK 自带:代理类需要实现和目标类一样的接口

  2. 开源项目 CGLib (Code Generation Library):代理类继承目标类

Spring 已经集成了 CGLib

示例代码:Spring - 动态代理

由我们手动实现代理,需要和前面所讲的 Spring 生命周期 BeanPostProcessor 结合起来,拦截每一个 bean 的生命周期,从而实现对每一个 bean 的代理(可以通过判断类名、方法等,来指定哪些对象需要代理)

JDK 动态代理 - Proxy.newProxyInstance

/**

  • 实现BeanPostProcessor接口会拦截每一个bean的生命周期

*/

public class LogProcessor implements BeanPostProcessor {

@Override

public Object postProcessAfterInitialization(Object target, String beanName) throws BeansException {

// 初始化方法调用前不做任何处理

return bean;

}

@Override

public Object postProcessAfterInitialization(Object target, String beanName) throws BeansException {

return Proxy.newProxyInstance(

getClass().getClassLoader(), // 类加载器

target.getClass().getInterfaces(), // 代理类需要实现的接口(目标类的接口)

new LogInvocationHandler(target)); // 附加代码

}

private static class LogInvocationHandler implements InvocationHandler {

private final Object target;

public LogInvocationHandler(Object target) {

this.target = target;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// proxy:代理对象

// method:目标方法

// args:目标方法的参数

System.out.println(“proxy - before”);

// 调用目标对象的目标方法(核心业务代码)

Object result = method.invoke(target, args);

System.out.println(“proxy - after”);

return result;

}

}

}

CGLib 动态代理 - Enhancer、MethodInterceptor

/**

  • 会拦截每一个bean的生命周期

*/

public class LogProcessor implements BeanPostProcessor {

@Override

public Object postProcessAfterInitialization(Object target, String beanName) throws BeansException {

// 某些类不需要代理

if (!beanName.endsWith(“Service”)) return target;

Enhancer enhancer = new Enhancer();

// enhancer.setClassLoader(getClass().getClassLoader()); // 可以省略

enhancer.setSuperclass(target.getClass());

enhancer.setCallback(new LogMethodInterceptor(target));

return enhancer.create();

}

// org.speringframework.cglib.proxy.MethodInterceptor

private static class LogMethodInterceptor implements MethodInterceptor {

private final Object target;

public LogMethodInterceptor(Object target) {

this.target = target;

}

总结

阿里伤透我心,疯狂复习刷题,终于喜提offer 哈哈~好啦,不闲扯了

image

1、JAVA面试核心知识整理(PDF):包含JVMJAVA集合JAVA多线程并发,JAVA基础,Spring原理微服务,Netty与RPC,网络,日志,ZookeeperKafkaRabbitMQ,Hbase,MongoDB,Cassandra,设计模式负载均衡数据库一致性哈希JAVA算法数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算共30个章节。

image

2、Redis学习笔记及学习思维脑图

image

3、数据面试必备20题+数据库性能优化的21个最佳实践

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

tTDgo7-1715587406397)]

2、Redis学习笔记及学习思维脑图

[外链图片转存中…(img-HCl7yQRO-1715587406397)]

3、数据面试必备20题+数据库性能优化的21个最佳实践

[外链图片转存中…(img-9QyUuXUk-1715587406397)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值