代码库详细笔记
一、JDK 动态代理实现
- 目标接口定义
// JdkService.java
public interface JdkService {void doSerivce(); // 注意:方法名存在拼写错误,应为doService
}// AA.java
public interface AA {String aa();
}
- 接口实现类
// EasyJdkService.java
public class EasyJdkService implements JdkService {@Overridepublic void doSerivce() {System.out.println("EasyJdkService 执行核心业务逻辑");}
}// EasyJdkServiceAA.java
public class EasyJdkServiceAA implements AA {@Overridepublic String aa() {System.out.println("EasyJdkServiceAA 执行aa()方法");return "aa";}
}
- InvocationHandler 实现类
// EasyInvocationHandler.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class EasyInvocationHandler implements InvocationHandler {private Object proxyedObj; // 被代理的目标对象// 通过构造器注入目标对象public EasyInvocationHandler(Object proxyedObj) {this.proxyedObj = proxyedObj;}/*** 代理方法执行逻辑* @param proxy 代理对象* @param method 目标方法* @param args 方法参数* @return 方法返回值* @throws Throwable 异常*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 前置增强:方法执行前的处理System.out.println("===== JDK代理 - 前置增强 =====");// 调用目标对象的真实方法Object result = method.invoke(proxyedObj, args);// 后置增强:方法执行后的处理System.out.println("===== JDK代理 - 后置增强 =====");return result;}
}
- 代理测试类
// JdkProxyTest.java
import java.lang.reflect.Proxy;public class JdkProxyTest {/*** 创建代理对象* @param obj 被代理对象* @return 代理对象*/public static Object getProxy(Object obj) {return Proxy.newProxyInstance(obj.getClass().getClassLoader(), // 类加载器obj.getClass().getInterfaces(), // 实现的接口new EasyInvocationHandler(obj) // 处理器);}public static void main(String[] args) {// 测试JdkService代理JdkService jdkService = new EasyJdkService();JdkService proxy = (JdkService) getProxy(jdkService);proxy.doSerivce(); // 调用代理方法// 测试AA接口代理AA aa = new EasyJdkServiceAA();AA aaProxy = (AA) getProxy(aa);String result = aaProxy.aa();System.out.println("方法返回值:" + result);}
}
二、静态代理实现
- 目标接口与实现类
// EasyService.java
public interface EasyService {void doService();
}// EasyBean.java (staticproxy包)
public class EasyBean implements EasyService {@Overridepublic void doService() {System.out.println("EasyBean 执行实际业务逻辑");}
}
- 静态代理类
// EasyProxy.java
public class EasyProxy implements EasyService {private EasyService easyService; // 持有被代理对象// 构造器注入被代理对象public EasyProxy(EasyService easyService) {this.easyService = easyService;}@Overridepublic void doService() {// 前置增强System.out.println("===== 静态代理 - 前置处理 =====");// 调用被代理对象的方法easyService.doService();// 后置增强System.out.println("===== 静态代理 - 后置处理 =====");}
}
- 静态代理测试
// EasyTest.java
public class EasyTest {public static void main(String[] args) {// 创建被代理对象EasyService target = new EasyBean();// 创建代理对象EasyService proxy = new EasyProxy(target);// 通过代理对象调用方法proxy.doService();}
}
三、Spring 相关组件
- Spring 配置类
// BeanConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.context.annotation.Scope;
import java.util.ArrayList;
import java.util.List;@Configuration // 标识为配置类
public class BeanConfig {// 定义Bean,指定初始化方法@Bean(initMethod = "initEasyBean")public EasyBean easyBean() {return new EasyBean();}// 定义Session作用域的List Bean@Bean@Scope(WebApplicationContext.SCOPE_SESSION)public List<String> list() {List<String> list = new ArrayList<>();list.add("zhangsan");list.add("lisisi");return list;}@Beanpublic List<String> lista() {List<String> list = new ArrayList<>();list.add("zhangsanA");list.add("lisisiA");return list;}
}
- 生命周期感知 Bean
// EasyBean.java (component包)
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;public class EasyBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {private String beanName;// 实现BeanNameAware接口,获取Bean名称@Overridepublic void setBeanName(String name) {this.beanName = name;System.out.println("BeanNameAware: " + name);}// 实现BeanFactoryAware接口,获取Bean工厂@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("BeanFactoryAware: " + beanFactory);}// 实现ApplicationContextAware接口,获取应用上下文@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("ApplicationContextAware: " + applicationContext);}// 实现InitializingBean接口,属性设置后执行@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("InitializingBean: afterPropertiesSet");}// 自定义初始化方法,通过@Bean(initMethod)指定public void initEasyBean() {System.out.println("自定义初始化方法: initEasyBean");}
}
- Bean 后置处理器
// EasyProcessor.java
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class EasyProcessor implements BeanPostProcessor {// 初始化之前执行@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("BeanPostProcessor: before - " + beanName);return bean;}// 初始化之后执行@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("BeanPostProcessor: after - " + beanName);return bean;}
}
- Service 组件
// UserService.java
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.BeanNameAware;@Service("userS") // 指定Bean名称
public class UserService implements BeanNameAware {@Overridepublic void setBeanName(String name) {System.out.println("UserService Bean名称: " + name);}
}// UserServiceA.java
import org.springframework.stereotype.Service;@Service("userSA")
public class UserServiceA {public void usera() {}public void userb() {}public void userc() {}
}
四、实体类
// User.java
public class User {private Integer id;private String username;private String password;// getter和setter方法public Integer getId() { return id; }public void setId(Integer id) { this.id = id; }public String getUsername() { return username; }public void setUsername(String username) { this.username = username; }public String getPassword() { return password; }public void setPassword(String password) { this.password = password; }
}
关键技术点总结
- JDK 动态代理:基于接口实现,通过
Proxy.newProxyInstance()
创建代理对象,核心是InvocationHandler
的invoke()
方法 - 静态代理:编译期确定代理关系,代理类与目标类实现同一接口,直接持有目标对象引用
- Spring IOC:通过
@Configuration
和@Bean
定义 Bean,支持自定义初始化方法和作用域 - Bean 生命周期:通过
BeanNameAware
等接口和BeanPostProcessor
可监控和干预 Bean 的创建过程 - 注解驱动:使用
@Service
等注解快速注册 Bean,简化配置
SpringBean的生命周期
文字描述:
1)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。
2)利用依赖注入完成 Bean 中所有属性值的配置注入。
3)如果Bean实现了特定的Aware接口(例如BeanNameAware、BeanFactoryAware、ApplicationContextAware等),Spring会在Bean的初始化过程中调用这些接口定义的方法,使Bean能够感知到容器的相关属性和功能。
如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
4)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
5)如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
6)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
7)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
8)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
10)如果在 <bean> 中指定了该 Bean 的作用范围为 scope="singleton",则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 <bean> 中指定了该 Bean 的作用范围为 scope="prototype",则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
11)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。
Spring 核心概念
- Spring 是一个分层的轻量级开源 Java 框架
- 两个核心内容:
- IoC(控制反转)
- AOP(面向切面)
IoC(控制反转)
- 概念:将对象的创建和管理权交给 Spring 容器,而非手动创建
- 举例:传统方式如同自己去超市买东西,IoC 则如同在手机上声明需求,由外卖(Spring 容器)送达
- 将类纳入 IoC 容器管理的注解:
@Controller
/@RestController
:用于访问层(Controller)@Service
:用于业务层@Repository
:用于数据访问层@Component
:用于其他组件@Configuration
+@Bean
:通过声明方法将返回对象纳入 IoC 容器,bean 的名称为方法名
DI(依赖注入)
- 概念:通过依赖关系将所需对象注入到目标类中
- 实现依赖注入的注解:
@Autowired
:- 默认通过
byType
(按类型)查找 bean - 若容器中存在多个同类型 bean,需配合
@Qualifier("beanName")
按byName
(按名称)查找
- 默认通过
@Resource
:- 默认通过
byName
查找 bean - 若找不到则自动切换为
byType
方式
- 默认通过
Spring Bean 的作用域
SCOPE_SINGLETON
:默认作用域,单例模式,整个运行过程中使用同一个对象SCOPE_PROTOTYPE
:原型模式,为每个需要注入的类提供新对象SCOPE_REQUEST
:每次请求创建新对象SCOPE_SESSION
:每次会话创建新对象(可通过@Scope(WebApplicationContext.SCOPE_SESSION)
配置)SCOPE_APPLICATION
:整个应用使用同一个对象
控制器(Controller)相关
- 访问层职责:获取参数、响应数据,不直接处理业务,业务逻辑由 Service 层完成
- 常用注解:
@Controller
:标识为控制器@RestController
:组合@Controller
和@ResponseBody
,响应数据为 JSON 等格式@RequestMapping("url")
:映射请求路径@ResponseBody
:将返回结果直接作为响应体(非跳转页面)
代码示例相关说明
- 在 Controller 中注入 Service 或其他组件,通过调用其方法完成业务操作(如
userService.usera()
) - 可通过
@Scope
注解指定控制器的作用域(如会话级别的控制器) - 会话相关:
HttpSession.invalidate()
可使当前会话失效