学习目标
深入学习Java高级特性,掌握JVM原理,理解Spring框架底层机制,学习安全与加密技术,掌握测试与质量保证方法,应用高级设计模式。
1. 高级并发编程
1.1 CompletableFuture异步编程
CompletableFuture深度应用:
java
// CompletableFuture基础使用
@Service
@Slf4j
public class CompletableFutureService {
// 创建异步任务
public CompletableFuture<String> asyncTask(String input) {
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
log.info("异步任务执行: input={}", input);
return "处理结果: " + input;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
});
}
// 链式调用
public CompletableFuture<String> chainAsyncTasks() {
return CompletableFuture
.supplyAsync(() -> {
log.info("第一步: 获取数据");
return "数据";
})
.thenApply(data -> {
log.info("第二步: 处理数据, data={}", data);
return "处理后的" + data;
})
.thenApply(processedData -> {
log.info("第三步: 保存数据, data={}", processedData);
return "保存成功: " + processedData;
})
.exceptionally(throwable -> {
log.error("处理失败", throwable);
return "处理失败";
});
}
// 组合多个异步任务
public CompletableFuture<String> combineAsyncTasks() {
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
log.info("任务1执行");
return "结果1";
});
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
log.info("任务2执行");
return "结果2";
});
// 等待所有任务完成
return task1.thenCombine(task2, (result1, result2) -> {
log.info("合并结果: result1={}, result2={}", result1, result2);
return result1 + " + " + result2;
});
}
// 并行执行多个任务
public CompletableFuture<List<String>> parallelTasks(List<String> inputs) {
List<CompletableFuture<String>> futures = inputs.stream()
.map(input -> CompletableFuture.supplyAsync(() -> {
log.info("处理: {}", input);
return "处理结果: " + input;
}))
.collect(Collectors.toList());
// 等待所有任务完成
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
futures.toArray(new CompletableFuture[0])
);
return allFutures.thenApply(v ->
futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList())
);
}
// 超时控制
public CompletableFuture<String> withTimeout(String input, long timeout, TimeUnit unit) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000); // 模拟长时间任务
return "结果: " + input;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
});
// 使用ScheduledExecutorService实现超时
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
CompletableFuture<String> timeoutFuture = new CompletableFuture<>();
scheduler.schedule(() -> {
if (!future.isDone()) {
timeoutFuture.completeExceptionally(new TimeoutException("任务超时"));
}
}, timeout, unit);
return future.applyToEither(timeoutFuture, Function.identity());
}
// 实际应用:并行查询多个数据源
public CompletableFuture<CombinedData> fetchCombinedData(Long userId) {
CompletableFuture<User> userFuture = CompletableFuture.supplyAsync(() ->
userService.getUserById(userId)
);
CompletableFuture<List<Order>> ordersFuture = CompletableFuture.supplyAsync(() ->
orderService.getUserOrders(userId)
);
CompletableFuture<List<Address>> addressesFuture = CompletableFuture.supplyAsync(() ->
addressService.getUserAddresses(userId)
);
return CompletableFuture.allOf(userFuture, ordersFuture, addressesFuture)
.thenApply(v -> {
CombinedData data = new CombinedData();
data.setUser(userFuture.join());
data.setOrders(ordersFuture.join());
data.setAddresses(addressesFuture.join());
return data;
});
}
}
// 组合数据
@Data
public class CombinedData {
private User user;
private List<Order> orders;
private List<Address> addresses;
}
1.2 ForkJoin框架
ForkJoin框架应用:
java
// ForkJoin任务:计算数组和
public class SumTask extends RecursiveTask<Long> {
private static final int THRESHOLD = 1000; // 阈值
private final int[] array;
private final int start;
private final int end;
public SumTask(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
int length = end - start;
// 如果任务足够小,直接计算
if (length <= THRESHOLD) {
return computeDirectly();
}
// 否则,分割任务
int middle = start + length / 2;
SumTask leftTask = new SumTask(array, start, middle);
SumTask rightTask = new SumTask(array, middle, end);
// 并行执行子任务
leftTask.fork();
Long rightResult = rightTask.compute();
Long leftResult = leftTask.join();
return leftResult + rightResult;
}
private Long computeDirectly() {
long sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
}
}
// ForkJoin使用示例
@Service
@Slf4j
public class ForkJoinService {
public Long calculateSum(int[] array) {
ForkJoinPool pool = new ForkJoinPool();
SumTask task = new SumTask(array, 0, array.length);
return pool.invoke(task);
}
// 并行处理大量数据
public List<String> parallelProcess(List<String> data) {
ForkJoinPool pool = new ForkJoinPool();
return pool.invoke(new RecursiveTask<List<String>>() {
@Override
protected List<String> compute() {
if (data.size() <= 100) {
// 直接处理
return data.stream()
.map(this::processItem)
.collect(Collectors.toList());
} else {
// 分割任务
int middle = data.size() / 2;
RecursiveTask<List<String>> leftTask = new RecursiveTask<List<String>>() {
@Override
protected List<String> compute() {
return parallelProcess(data.subList(0, middle));
}
};
RecursiveTask<List<String>> rightTask = new RecursiveTask<List<String>>() {
@Override
protected List<String> compute() {
return parallelProcess(data.subList(middle, data.size()));
}
};
leftTask.fork();
List<String> rightResult = rightTask.compute();
List<String> leftResult = leftTask.join();
List<String> result = new ArrayList<>(leftResult);
result.addAll(rightResult);
return result;
}
}
private String processItem(String item) {
// 处理逻辑
return "处理后的: " + item;
}
});
}
}
1.3 并发集合深度应用
并发集合使用:
java
// ConcurrentHashMap深度应用
@Service
@Slf4j
public class ConcurrentCollectionService {
private final ConcurrentHashMap<String, AtomicInteger> counterMap = new ConcurrentHashMap<>();
// 线程安全的计数器
public void increment(String key) {
counterMap.computeIfAbsent(key, k -> new AtomicInteger(0)).incrementAndGet();
}
// 原子操作
public int addAndGet(String key, int delta) {
return counterMap.computeIfAbsent(key, k -> new AtomicInteger(0)).addAndGet(delta);
}
// 批量操作
public void batchIncrement(Map<String, Integer> increments) {
increments.forEach((key, value) ->
counterMap.computeIfAbsent(key, k -> new AtomicInteger(0)).addAndGet(value)
);
}
// ConcurrentHashMap的reduce操作
public int sumAllValues() {
return counterMap.reduceValuesToInt(
Integer.MAX_VALUE,
AtomicInteger::get,
0,
Integer::sum
);
}
// CopyOnWriteArrayList应用
private final CopyOnWriteArrayList<String> logList = new CopyOnWriteArrayList<>();
public void addLog(String log) {
logList.add(log);
}
public List<String> getAllLogs() {
return new ArrayList<>(logList);
}
// BlockingQueue应用:生产者消费者
private final BlockingQueue<Order> orderQueue = new LinkedBlockingQueue<>(1000);
@Async
public void produceOrder(Order order) throws InterruptedException {
orderQueue.put(order);
log.info("生产订单: {}", order.getOrderNumber());
}
@Async
public void consumeOrder() throws InterruptedException {
while (true) {
Order order = orderQueue.take();
processOrder(order);
}
}
private void processOrder(Order order) {
log.info("处理订单: {}", order.getOrderNumber());
// 处理逻辑
}
// ConcurrentLinkedQueue应用
private final ConcurrentLinkedQueue<Task> taskQueue = new ConcurrentLinkedQueue<>();
public void submitTask(Task task) {
taskQueue.offer(task);
}
public Task pollTask() {
return taskQueue.poll();
}
}
2. JVM深度原理
2.1 类加载机制
类加载器实现:
java
// 自定义类加载器
public class CustomClassLoader extends ClassLoader {
private final String classPath;
public CustomClassLoader(String classPath) {
this.classPath = classPath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = loadClassData(name);
if (classData == null) {
throw new ClassNotFoundException("类未找到: " + name);
}
return defineClass(name, classData, 0, classData.length);
}
private byte[] loadClassData(String className) {
String fileName = classPath + className.replace('.', File.separatorChar) + ".class";
try (FileInputStream fis = new FileInputStream(fileName);
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
return baos.toByteArray();
} catch (IOException e) {
return null;
}
}
}
// 类加载器应用
@Service
@Slf4j
public class ClassLoaderService {
// 获取类加载器信息
public ClassLoaderInfo getClassLoaderInfo() {
ClassLoaderInfo info = new ClassLoaderInfo();
ClassLoader currentLoader = this.getClass().getClassLoader();
info.setCurrentClassLoader(currentLoader.getClass().getName());
// 获取父类加载器
ClassLoader parent = currentLoader.getParent();
if (parent != null) {
info.setParentClassLoader(parent.getClass().getName());
}
// 获取系统类加载器
ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
info.setSystemClassLoader(systemLoader.getClass().getName());
return info;
}
// 动态加载类
public Class<?> loadClassDynamically(String className, String classPath) throws Exception {
CustomClassLoader loader = new CustomClassLoader(classPath);
return loader.loadClass(className);
}
// 获取类的加载信息
public ClassInfo getClassInfo(String className) throws ClassNotFoundException {
Class<?> clazz = Class.forName(className);
ClassInfo info = new ClassInfo();
info.setClassName(clazz.getName());
info.setSimpleName(clazz.getSimpleName());
info.setClassLoader(clazz.getClassLoader().getClass().getName());
info.setInterfaces(Arrays.stream(clazz.getInterfaces())
.map(Class::getName)
.collect(Collectors.toList()));
info.setSuperClass(clazz.getSuperclass() != null ? clazz.getSuperclass().getName() : null);
return info;
}
}
// 类加载器信息
@Data
public class ClassLoaderInfo {
private String currentClassLoader;
private String parentClassLoader;
private String systemClassLoader;
}
// 类信息
@Data
public class ClassInfo {
private String className;
private String simpleName;
private String classLoader;
private List<String> interfaces;
private String superClass;
}
2.2 内存模型与可见性
Java内存模型应用:
java
// volatile关键字应用
@Service
@Slf4j
public class MemoryModelService {
// volatile保证可见性
private volatile boolean running = true;
private volatile int counter = 0;
// 启动线程
public void startWorker() {
Thread worker = new Thread(() -> {
while (running) {
counter++;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
});
worker.start();
}
// 停止线程
public void stopWorker() {
running = false; // volatile保证其他线程能立即看到这个变化
}
public int getCounter() {
return counter; // volatile保证读取到最新值
}
// synchronized保证可见性和原子性
private int sharedCounter = 0;
private final Object lock = new Object();
public void incrementSharedCounter() {
synchronized (lock) {
sharedCounter++; // 原子操作
}
}
public int getSharedCounter() {
synchronized (lock) {
return sharedCounter; // 保证读取到最新值
}
}
// CAS操作(Compare-And-Swap)
private final AtomicInteger atomicCounter = new AtomicInteger(0);
public void incrementAtomicCounter() {
atomicCounter.incrementAndGet();
}
public int getAtomicCounter() {
return atomicCounter.get();
}
// 使用CAS实现自旋锁
private final AtomicBoolean locked = new AtomicBoolean(false);
public void lock() {
while (!locked.compareAndSet(false, true)) {
// 自旋等待
Thread.yield();
}
}
public void unlock() {
locked.set(false);
}
}
// 内存屏障示例
@Service
@Slf4j
public class MemoryBarrierService {
private int x = 0;
private int y = 0;
private volatile boolean flag = false;
// 写操作
public void write() {
x = 1;
y = 2;
flag = true; // volatile写,插入StoreStore和StoreLoad屏障
}
// 读操作
public void read() {
if (flag) { // volatile读,插入LoadLoad和LoadStore屏障
int a = x;
int b = y;
log.info("读取值: a={}, b={}", a, b);
}
}
}
2.3 GC算法深入
GC监控与调优:
java
// GC监控服务
@Service
@Slf4j
public class GCMonitorService {
// 获取GC信息
public List<GCStatistics> getGCStatistics() {
List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();
List<GCStatistics> statistics = new ArrayList<>();
for (GarbageCollectorMXBean gcBean : gcBeans) {
GCStatistics stats = new GCStatistics();
stats.setName(gcBean.getName());
stats.setCollectionCount(gcBean.getCollectionCount());
stats.setCollectionTime(gcBean.getCollectionTime());
// 获取内存池信息
MemoryUsage usage = getMemoryUsage(gcBean.getName());
if (usage != null) {
stats.setUsedMemory(usage.getUsed());
stats.setMaxMemory(usage.getMax());
}
statistics.add(stats);
}
return statistics;
}
// 获取内存使用情况
public MemoryUsageInfo getMemoryUsageInfo() {
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();
MemoryUsageInfo info = new MemoryUsageInfo();
info.setHeapUsed(heapUsage.getUsed());
info.setHeapMax(heapUsage.getMax());
info.setHeapCommitted(heapUsage.getCommitted());
info.setNonHeapUsed(nonHeapUsage.getUsed());
info.setNonHeapMax(nonHeapUsage.getMax());
info.setNonHeapCommitted(nonHeapUsage.getCommitted());
return info;
}
// 触发GC(仅用于测试)
public void triggerGC() {
System.gc();
log.info("手动触发GC");
}
// GC调优建议
public List<String> getGCTuningSuggestions() {
List<String> suggestions = new ArrayList<>();
MemoryUsageInfo info = getMemoryUsageInfo();
// 检查堆内存使用率
double heapUsageRate = (double) info.getHeapUsed() / info.getHeapMax() * 100;
if (heapUsageRate > 80) {
suggestions.add("堆内存使用率过高(" + String.format("%.2f%%", heapUsageRate) +
"),建议增加堆内存: -Xmx4g -Xms4g");
}
// 检查GC频率
List<GCStatistics> gcStats = getGCStatistics();
for (GCStatistics stats : gcStats) {
if (stats.getCollectionCount() > 1000) {
suggestions.add("GC频率过高(" + stats.getName() + "执行了" +
stats.getCollectionCount() + "次),建议使用G1GC: -XX:+UseG1GC");
}
}
return suggestions;
}
private MemoryUsage getMemoryUsage(String gcName) {
// 根据GC名称获取对应的内存池使用情况
List<MemoryPoolMXBean> poolBeans = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean poolBean : poolBeans) {
if (poolBean.getName().contains(gcName)) {
return poolBean.getUsage();
}
}
return null;
}
}
// GC统计信息
@Data
public class GCStatistics {
private String name;
private long collectionCount;
private long collectionTime;
private long usedMemory;
private long maxMemory;
}
// 内存使用信息
@Data
public class MemoryUsageInfo {
private long heapUsed;
private long heapMax;
private long heapCommitted;
private long nonHeapUsed;
private long nonHeapMax;
private long nonHeapCommitted;
}
3. Spring高级特性
3.1 AOP原理深入
AOP底层实现:
java
// 自定义AOP实现
@Aspect
@Component
@Slf4j
public class CustomAspect {
// 前置通知
@Before("execution(* com.example.service.*.*(..))")
public void beforeAdvice(JoinPoint joinPoint) {
log.info("前置通知: 方法={}, 参数={}",
joinPoint.getSignature().getName(),
Arrays.toString(joinPoint.getArgs()));
}
// 后置通知
@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
log.info("后置通知: 方法={}, 返回值={}",
joinPoint.getSignature().getName(), result);
}
// 异常通知
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "exception")
public void afterThrowingAdvice(JoinPoint joinPoint, Exception exception) {
log.error("异常通知: 方法={}, 异常={}",
joinPoint.getSignature().getName(), exception.getMessage());
}
// 环绕通知
@Around("execution(* com.example.service.*.*(..))")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
try {
// 前置处理
log.info("环绕通知-前置: 方法={}", joinPoint.getSignature().getName());
// 执行目标方法
Object result = joinPoint.proceed();
// 后置处理
long executionTime = System.currentTimeMillis() - startTime;
log.info("环绕通知-后置: 方法={}, 执行时间={}ms",
joinPoint.getSignature().getName(), executionTime);
return result;
} catch (Exception e) {
log.error("环绕通知-异常: 方法={}, 异常={}",
joinPoint.getSignature().getName(), e.getMessage());
throw e;
}
}
// 自定义切点
@Pointcut("execution(* com.example.service.*.*(..)) && @annotation(com.example.annotation.Log)")
public void logPointcut() {}
@Around("logPointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Log logAnnotation = method.getAnnotation(Log.class);
String description = logAnnotation != null ? logAnnotation.value() : method.getName();
log.info("开始执行: {}", description);
try {
Object result = joinPoint.proceed();
log.info("执行成功: {}", description);
return result;
} catch (Exception e) {
log.error("执行失败: {}, 异常: {}", description, e.getMessage());
throw e;
}
}
}
// 自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
// AOP代理分析
@Service
@Slf4j
public class AOPAnalysisService {
@Autowired
private ApplicationContext applicationContext;
// 分析Bean的代理类型
public ProxyInfo analyzeProxy(String beanName) {
Object bean = applicationContext.getBean(beanName);
ProxyInfo info = new ProxyInfo();
info.setBeanName(beanName);
info.setBeanClass(bean.getClass().getName());
info.setInterfaces(Arrays.stream(bean.getClass().getInterfaces())
.map(Class::getName)
.collect(Collectors.toList()));
// 检查是否是JDK动态代理
if (Proxy.isProxyClass(bean.getClass())) {
info.setProxyType("JDK动态代理");
}
// 检查是否是CGLIB代理
else if (bean.getClass().getName().contains("CGLIB")) {
info.setProxyType("CGLIB代理");
} else {
info.setProxyType("非代理");
}
return info;
}
}
// 代理信息
@Data
public class ProxyInfo {
private String beanName;
private String beanClass;
private String proxyType;
private List<String> interfaces;
}
3.2 事务源码分析
事务管理深入:
java
// 事务管理器分析
@Service
@Slf4j
public class TransactionAnalysisService {
@Autowired
private PlatformTransactionManager transactionManager;
// 编程式事务
@Transactional
public void programmaticTransaction() {
TransactionStatus status = transactionManager.getTransaction(
new DefaultTransactionDefinition()
);
try {
// 业务逻辑
log.info("执行事务操作");
// 提交事务
transactionManager.commit(status);
} catch (Exception e) {
// 回滚事务
transactionManager.rollback(status);
throw e;
}
}
// 事务传播行为测试
@Transactional(propagation = Propagation.REQUIRED)
public void methodWithRequired() {
log.info("REQUIRED传播行为");
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodWithRequiresNew() {
log.info("REQUIRES_NEW传播行为");
}
@Transactional(propagation = Propagation.NESTED)
public void methodWithNested() {
log.info("NESTED传播行为");
}
// 事务隔离级别测试
@Transactional(isolation = Isolation.READ_COMMITTED)
public void methodWithReadCommitted() {
log.info("READ_COMMITTED隔离级别");
}
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void methodWithRepeatableRead() {
log.info("REPEATABLE_READ隔离级别");
}
@Transactional(isolation = Isolation.SERIALIZABLE)
public void methodWithSerializable() {
log.info("SERIALIZABLE隔离级别");
}
// 获取当前事务信息
public TransactionInfo getCurrentTransactionInfo() {
TransactionInfo info = new TransactionInfo();
if (TransactionSynchronizationManager.isActualTransactionActive()) {
info.setActive(true);
info.setTransactionName(TransactionSynchronizationManager.getCurrentTransactionName());
info.setIsolationLevel(TransactionSynchronizationManager.getCurrentTransactionIsolationLevel());
info.setReadOnly(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
} else {
info.setActive(false);
}
return info;
}
}
// 事务信息
@Data
public class TransactionInfo {
private boolean active;
private String transactionName;
private Integer isolationLevel;
private boolean readOnly;
}
3.3 Bean生命周期深入
Bean生命周期管理:
java
// Bean生命周期回调
@Component
@Slf4j
public class LifecycleBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware {
private String beanName;
private BeanFactory beanFactory;
// BeanNameAware接口
@Override
public void setBeanName(String name) {
this.beanName = name;
log.info("1. BeanNameAware.setBeanName: {}", name);
}
// BeanFactoryAware接口
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
log.info("2. BeanFactoryAware.setBeanFactory");
}
// @PostConstruct注解
@PostConstruct
public void postConstruct() {
log.info("3. @PostConstruct方法执行");
}
// InitializingBean接口
@Override
public void afterPropertiesSet() throws Exception {
log.info("4. InitializingBean.afterPropertiesSet");
}
// 自定义初始化方法
public void customInit() {
log.info("5. 自定义初始化方法");
}
// @PreDestroy注解
@PreDestroy
public void preDestroy() {
log.info("6. @PreDestroy方法执行");
}
// DisposableBean接口
@Override
public void destroy() throws Exception {
log.info("7. DisposableBean.destroy");
}
// 自定义销毁方法
public void customDestroy() {
log.info("8. 自定义销毁方法");
}
}
// Bean后置处理器
@Component
@Slf4j
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.info("BeanPostProcessor.postProcessBeforeInitialization: beanName={}, beanClass={}",
beanName, bean.getClass().getName());
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
log.info("BeanPostProcessor.postProcessAfterInitialization: beanName={}, beanClass={}",
beanName, bean.getClass().getName());
return bean;
}
}
4. 安全与加密
4.1 Spring Security深度应用
Spring Security配置:
java
// Spring Security配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
// JWT工具类
@Component
@Slf4j
public class JwtTokenUtil {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
// 生成Token
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
claims.put("sub", userDetails.getUsername());
claims.put("authorities", userDetails.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList()));
return createToken(claims, userDetails.getUsername());
}
private String createToken(Map<String, Object> claims, String subject) {
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
// 验证Token
public Boolean validateToken(String token, UserDetails userDetails) {
final String username = getUsernameFromToken(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
// 从Token获取用户名
public String getUsernameFromToken(String token) {
return getClaimFromToken(token, Claims::getSubject);
}
// 获取Token过期时间
public Date getExpirationDateFromToken(String token) {
return getClaimFromToken(token, Claims::getExpiration);
}
public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
final Claims claims = getAllClaimsFromToken(token);
return claimsResolver.apply(claims);
}
private Claims getAllClaimsFromToken(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
}
private Boolean isTokenExpired(String token) {
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(new Date());
}
}
// JWT请求过滤器
@Component
@Slf4j
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
final String requestTokenHeader = request.getHeader("Authorization");
String username = null;
String jwtToken = null;
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
jwtToken = requestTokenHeader.substring(7);
try {
username = jwtTokenUtil.getUsernameFromToken(jwtToken);
} catch (IllegalArgumentException e) {
log.error("无法获取JWT Token");
} catch (ExpiredJwtException e) {
log.warn("JWT Token已过期");
}
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
chain.doFilter(request, response);
}
}
4.2 数据加密
数据加密实现:
java
// 加密服务
@Service
@Slf4j
public class EncryptionService {
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
@Value("${encryption.secret-key}")
private String secretKey;
// AES加密
public String encrypt(String plainText) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encrypted = cipher.doFinal(plainText.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
// AES解密
public String decrypt(String encryptedText) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decrypted);
}
// MD5哈希
public String md5Hash(String input) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hashBytes = md.digest(input.getBytes());
return bytesToHex(hashBytes);
}
// SHA-256哈希
public String sha256Hash(String input) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = md.digest(input.getBytes());
return bytesToHex(hashBytes);
}
// RSA加密(非对称加密)
public String rsaEncrypt(String plainText, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(plainText.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
// RSA解密
public String rsaDecrypt(String encryptedText, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decrypted);
}
// 生成RSA密钥对
public KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
return keyPairGenerator.generateKeyPair();
}
private String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02x", b));
}
return result.toString();
}
}
5. 测试与质量保证
5.1 单元测试
JUnit 5测试:
java
// 单元测试示例
@SpringBootTest
@ExtendWith(MockitoExtension.class)
@Slf4j
class OrderServiceTest {
@Mock
private OrderRepository orderRepository;
@Mock
private ProductService productService;
@InjectMocks
private OrderService orderService;
@Test
@DisplayName("测试创建订单")
void testCreateOrder() {
// Given
CreateOrderRequest request = new CreateOrderRequest();
request.setUserId(1L);
Product product = new Product();
product.setId(1L);
product.setPrice(new BigDecimal("100.00"));
product.setStock(10);
when(productService.getProductById(1L)).thenReturn(product);
when(orderRepository.save(any(Order.class))).thenAnswer(invocation -> {
Order order = invocation.getArgument(0);
order.setId(1L);
return order;
});
// When
OrderDTO result = orderService.createOrder(request);
// Then
assertNotNull(result);
assertEquals(1L, result.getUserId());
verify(orderRepository, times(1)).save(any(Order.class));
}
@Test
@DisplayName("测试库存不足")
void testInsufficientStock() {
// Given
CreateOrderRequest request = new CreateOrderRequest();
Product product = new Product();
product.setStock(0);
when(productService.getProductById(1L)).thenReturn(product);
// When & Then
assertThrows(InsufficientInventoryException.class, () -> {
orderService.createOrder(request);
});
}
@ParameterizedTest
@ValueSource(longs = {1L, 2L, 3L})
@DisplayName("参数化测试")
void testGetOrder(Long orderId) {
Order order = new Order();
order.setId(orderId);
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
OrderDTO result = orderService.getOrder(orderId);
assertNotNull(result);
assertEquals(orderId, result.getId());
}
}
5.2 集成测试
集成测试示例:
java
// 集成测试
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@Slf4j
class OrderControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Test
@DisplayName("集成测试:创建订单")
void testCreateOrderIntegration() throws Exception {
CreateOrderRequest request = new CreateOrderRequest();
request.setUserId(1L);
mockMvc.perform(post("/api/orders")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(200))
.andExpect(jsonPath("$.data").exists());
}
}
6. 高级设计模式
6.1 责任链模式
责任链模式实现:
java
// 责任链处理器接口
public interface Handler {
void setNext(Handler handler);
void handle(Request request);
}
// 抽象处理器
public abstract class AbstractHandler implements Handler {
private Handler next;
@Override
public void setNext(Handler handler) {
this.next = handler;
}
@Override
public void handle(Request request) {
if (canHandle(request)) {
doHandle(request);
} else if (next != null) {
next.handle(request);
}
}
protected abstract boolean canHandle(Request request);
protected abstract void doHandle(Request request);
}
// 具体处理器
@Component
public class AuthenticationHandler extends AbstractHandler {
@Override
protected boolean canHandle(Request request) {
return request.getType().equals("AUTH");
}
@Override
protected void doHandle(Request request) {
log.info("处理认证请求");
}
}
@Component
public class AuthorizationHandler extends AbstractHandler {
@Override
protected boolean canHandle(Request request) {
return request.getType().equals("AUTHZ");
}
@Override
protected void doHandle(Request request) {
log.info("处理授权请求");
}
}