先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
4.2spring-context.xml中的< beans >内部配置bean
在spring-context.xml中配置MyClass的bean后,当项目启动时,spring容器会自动创建MyClass实例,这个实例名字叫mc
测试代码
public class TestFactory{
/**
- 程序中的对象都交由Spring的ApplicationContext工厂进行创建。
*/
public static void main(String[] args){
//1. 读取配置文件中所需创建的bean对象,并获得工厂对象
ApplicationContext ctx = new ClassPathXmlApplicationContext(“spring-context.xml”);
//2. 通过id获取bean对象
MyClass mc = (MyClass) ctx.getBean(“mc”);
//3. 使用对象
mc.show();
}
}
5 IoC(Inversion of Control )控制反转
控制反转是Spring框架的核心,所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的, 这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。这样就由之前的自己创建依赖对象,变为由spring容器创建。(变主动为被动,即反转)。控制反转解决了具有依赖关系的组件之间的强耦合,使得项目形态更加稳健。
5.1 项目中强耦合问题
public class UserDAOImpl implements UserDAO{…}
public class UserServiceImpl implements UserService {
// 通过传统的new方式强耦合了UserDAOImpl!!!,使得UserServiceImpl变得不稳健!!
private UserDAO userDAO= new UserDAOImpl();
@Override
public User queryUser() {
return userDAO.queryUser();
}
…
}
5.2 解决方案
// 不引用任何一个具体的组件(实现类),在需要其他组件的位置预留存取值入口(set/get)
public class UserServiceImpl implements UserService {
// !!!不再耦合任何DAO实现!!!,消除不稳健因素!!
private UserDAO userDAO;
// 为userDAO定义set/get,允许userDAO属性接收spring赋值
//Getters And Setters
@Override
public User queryUser() {
return userDAO.queryUser();
}
…
}
在spring配置文件中配置UserDAO和UserService对应的bean
6 DI(Dependency Injection)依赖注入
6.1 概念
在Spring创建对象的同时,为其属性赋值,称之为依赖注入,注入方式主要有以下2种
- 构造函数注入
- Setter方法注入
6.2 Setter方法注入
创建对象时,Spring工厂会通过Setter方法为对象的属性赋值。
6.2.1 定义目标Bean类型
public class User {
private Integer id;
private String password;
private String sex;
private Integer age;
private Date bornDate;
private String[] hobbys;
private Set phones;
private List names;
private Map<String,String> countries;
private Properties files;
//Getters And Setters
}
6.2.2 基本类型 + 字符串类型 + 日期类型
6.2.3 容器类型(list,set,map,Properties)
Run Swim Climb 13777777777 13888888888 13999999999 tom jack marry One Two Three6.2.4 自定义类型
6.3 构造注入
创建对象时,Spring工厂会通过构造方法为对象的属性赋值。
6.3.1 定义目标Bean类型
public class Student {
private Integer id;
private String name;
private String sex;
private Integer age;
//Constructors
public Student(Integer id , String name , String sex , Integer age){
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
}
}
复制代码
6.3.2 注入
7 Spring工厂特性
7.1 饿汉式创建优势
工厂创建之后,会将Spring配置文件中的所有对象都创建完成(饿汉式),提高程序运行效率,避免多次IO,减少对象创建时间。(概念接近连接池,一次性创建好,使用时直接获取)
7.2 生命周期方法
- 自定义初始化方法:添加“init-method”属性,Spring则会在创建对象之后,调用此方法。
- 自定义销毁方法:添加“destroy-method”属性,Spring则会在销毁对象之前,调用此方法。
- 销毁:工厂的close()方法被调用之后,Spring会毁掉所有已创建的单例对象。
- 分类:Singleton对象由Spring容器销毁、Prototype对象由JVM销毁。
7.3 生命周期注解
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@PostConstruct //初始化
public void init(){
System.out.println(“init method executed”);
}
@PreDestroy //销毁
public void destroy(){
System.out.println(“destroy method executed”);
}
7.4 生命周期阶段
单例bean:singleton
随工厂启动创建 ==》 构造方法 ==》 set方法(注入值) ==》 init(初始化) ==》 构建完成 ==》随工厂关闭销毁
多例bean:prototype
被使用时创建 ==》 构造方法 ==》 set方法(注入值) ==》 init(初始化) ==》 构建完成 ==》JVM垃圾回收销毁
8 代理设计模式
8.1 概念
将核心功能与辅助功能(事务、日志、性能监控代码)分离,达到核心业务功能更纯粹、辅助业务功能可复用。
8.2 静态代理设计模式
通过代理类的对象,为原始类的对象(目标类的对象)添加辅助功能,更容易更换代理实现类、利于维护。
- 代理类 = 实现原始类相同接口 + 添加辅助功能 + 调用原始类的业务方法。
- 静态代理的问题 代理类数量过多,不利于项目的管理。 多个代理类的辅助功能代码冗余,修改时,维护性差。
8.3 动态代理设计模式
8.3.1 JDK动态代理实现(基于接口)
//目标
final OrderService os = new OrderServiceImpl();
//额外功能
InvocationHandler handler = new InvocationHandler(){//1.设置回调函数(额外功能代码)
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(“start…”);
method.invoke(os, args);
System.out.println(“end…”);
return null;
}
};
//2.创建动态代理类
Object proxyObj = Proxy.newProxyInstance(ClassLoader , Interfaces , InvocationHandler);
8.3.2 CGlib动态代理实现(基于继承)
final OrderService os = new OrderServiceImpl();
Enhancer cnh = new Enhancer();//1.创建字节码曾强对象
enh.setSuperclass(os.getClass());//2.设置父类(等价于实现原始类接口)
enh.setCallback(new InvocationHandler(){//3.设置回调函数(额外功能代码)
@Override
public Object invoke(Object proxy , Method method, Object[] args) throws Throwable{
System.out.println(“start…”);
Object ret = method.invoke(os,args);
System.out.println(“end…”);
return ret;
}
});
OrderService proxy = (OrderService)enh.create();//4.创建动态代理类
proxy,createOrder();
9 面向切面编程
9.1 概念
AOP(Aspect Oriented Programming),即面向切面编程,利用一种称为"横切"的技术,剖开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
通俗的概念来讲,所谓的面向切面编程就是针对被代理对象的方法在某个特定的执行时机(方法调用之前、方法调用之后、方法抛出异常),做出一些额外的横向的处理。好处在于:1. 可以在不修改原有代码基础上横向扩展我们的内容;2. 将一些方法中的通用逻辑进行统一化的处理。
OOP(面向对象编程)和AOP(面向切面编程)的区别:oop是对类纵向的扩展;aop是横向的扩展。
9.2 AOP开发术语
- 连接点(Joinpoint):连接点是程序类中客观存在的方法,可被Spring拦截并切入内容。
- 切入点(Pointcut):被切入连接点。
- 通知、增强(Advice):可以为切入点添加额外功能,分为:前置通知、后置通知、异常通知、环绕通知等。
- 目标对象(Target):代理的目标对象
- 织入(Weaving):把通知应用到具体的类,进而创建新的代理类的过程。
- 代理(Proxy):被AOP织入通知后,产生的结果类。
- 切面(Aspect):由切点和通知组成,将横切逻辑织入切面所指定的连接点中。
9.3 作用
Spring的AOP编程即是通过动态代理类为原始类的方法添加辅助功能。
9.4 环境搭建
引入AOP相关依赖
org.springframework spring-aspects 5.1.6.RELEASEspring-context.xml引入AOP命名空间
<?xml version="1.0" encoding="UTF-8"?>
9.5 开发流程
定义原始类
package com.qf.aaron.aop.basic;
public interface UserService {
public void save();
}
复制代码
package com.qf.aaron.aop.basic;
public class UserServiceImpl implements UserService {
public void save() {
System.out.println(“save method executed…”);
}
}
定义通知类(添加额外功能
package com.qf.aaron.aop.basic;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class MyAdvice implements MethodBeforeAdvice { //实现前置通知接口
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(“before advice executed…”);
}
}
定义bean标签
定义切入点(PointCut)
形成切面(Aspect)
aop:config
<aop:pointcut id=“myPointCut” expression=“execution(* save())” />
</aop:config>
aop:config
<aop:advisor advice-ref=“myAdvice” pointcut-ref=“myPointCut” />
</aop:config>
9.6 通知类
可定义的通知类有6种,可以按需求选择通知类。
前置通知:MethodBeforeAdvice
后置通知:AfterAdvice
后置通知:AfterReturningAdvice //有异常不执行,方法会因异常而结束,无返回值
异常通知:ThrowsAdvice
环绕通知:MethodInterceptor
9.7 JDK动态代理和CGLIB动态代理的选择
- spring底层,包含了jdk代理和cglib代理两种动态代理生成机制
- 基本规则是:目标业务类如果有接口则用JDK代理,没有接口则用CGLib代理
但是spring中默认开启JDK动态代理,当需要使用CGLIB动态代理时,需要在spring配置文件中配置。
<aop:aspectj-autoproxy proxy-target-class=“true”/>
10 基于aspectJ的AOP实现
编写aspectJ通知代码:
@Aspect
public class AspectJAdvisor {
// 环绕通知
@Around(“execution(* org.example.service.impl..(…))”)
public Object timer(ProceedingJoinPoint pjp) throws Throwable{
最后
针对以上面试题,小编已经把面试题+答案整理好了
面试专题
除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
713391886611)]
[外链图片转存中…(img-Px9X8f4N-1713391886611)]
面试专题
[外链图片转存中…(img-styEh6zb-1713391886612)]
除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习
[外链图片转存中…(img-R4809317-1713391886612)]
[外链图片转存中…(img-ZOv9wkmU-1713391886612)]
[外链图片转存中…(img-3qkGNxKk-1713391886613)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-qXUCsXsO-1713391886613)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!