Spring源码中的设计模式详解
Spring源码中的设计模式详解
Spring框架作为Java开发中最流行的框架之一,其优雅的架构设计离不开对设计模式的巧妙运用。本文将结合Spring源码,重点讲解代理模式、适配器模式、装饰器模式和工厂模式在Spring中的应用。
什么是设计模式?
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
1. 代理模式(Proxy Pattern)
什么是代理模式?
代理模式为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
Spring中的应用
Spring中最经典的代理模式应用就是**AOP(面向切面编程)**的实现。
动态代理示例
Spring AOP主要通过两种方式实现动态代理:
- JDK动态代理(基于接口)
- CGLIB代理(基于类)
Spring源码中的关键类:
org.springframework.aop.framework.JdkDynamicAopProxyorg.springframework.aop.framework.CglibAopProxy
// Spring源码中的Jdk动态代理实现片段
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
private final AdvisedSupport advised;
public JdkDynamicAopProxy(AdvisedSupport config) {
this.advised = config;
}
@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
@Override
public Object getProxy(ClassLoader classLoader) {
return Proxy.newProxyInstance(classLoader,
this.advised.getTargetClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation = null;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
try {
// 执行目标方法
return retVal;
} finally {
// 清理工作
}
}
}
实际应用场景
@Service
public class UserServiceImpl implements UserService {
@Override
public void saveUser(User user) {
System.out.println("保存用户: " + user.getName());
}
@Override
public void deleteUser(Long userId) {
System.out.println("删除用户: " + userId);
}
}
// 使用Spring AOP添加日志切面
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("执行方法: " + joinPoint.getSignature().getName());
}
@After("execution(* com.example.service.*.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("方法执行完毕: " + joinPoint.getSignature().getName());
}
}
代理模式的优势
- 职责清晰:真实角色只需关注业务逻辑
- 高扩展性:代理对象可以在不修改真实对象的情况下增加额外功能
- 智能化:动态代理可以在运行时决定调用哪个对象
2. 适配器模式(Adapter Pattern)
什么是适配器模式?
适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
Spring中的应用
Spring中适配器模式的应用非常广泛,主要体现在以下几个方面:
2.1 Spring MVC中的适配器
在Spring MVC中,不同的Controller类型(如注解@Controller、实现Controller接口、HttpRequestHandler等)通过适配器模式统一处理。
关键类:
org.springframework.web.servlet.HandlerAdapterorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapterorg.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
// HandlerAdapter接口定义
public interface HandlerAdapter {
boolean supports(Object handler);
ModelAndView handle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception;
long getLastModified(HttpServletRequest request, Object handler);
}
// RequestMappingHandlerAdapter实现
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
implements BeanFactoryAware, InitializingBean {
@Override
protected boolean supportsInternal(HandlerMethod handlerMethod) {
return true;
}
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response,
HandlerMethod handlerMethod) throws Exception {
// 处理注解类型的Controller
return invokeHandlerMethod(request, response, handlerMethod);
}
}
// HttpRequestHandlerAdapter实现
public class HttpRequestHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpRequestHandler);
}
@Override
public ModelAndView handle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
((HttpRequestHandler) handler).handleRequest(request, response);
return null;
}
}
2.2 Spring AOP中的适配器
Spring AOP通过适配器模式将不同的Advice(通知)类型适配到统一的拦截器链中。
关键类:
org.springframework.aop.framework.adapter.AdvisorAdapterorg.springframework.aop.framework.adapter.MethodBeforeAdviceAdapterorg.springframework.aop.framework.adapter.AfterReturningAdviceAdapter
// AdvisorAdapter接口
public interface AdvisorAdapter {
boolean supportsAdvice(Advice advice);
MethodInterceptor getInterceptor(Advisor advisor);
}
// MethodBeforeAdviceAdapter实现
public class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
// 适配器实现
class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private final MethodBeforeAdvice advice;
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 在目标方法执行前执行
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
}
适配器模式的优势
- 解耦:将接口转换逻辑独立出来,不修改原有代码
- 复用:提高了类的复用性
- 灵活:可以灵活地添加新的适配器
3. 装饰器模式(Decorator Pattern)
什么是装饰器模式?
装饰器模式动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
Spring中的应用
Spring中装饰器模式的典型应用是在Bean的生命周期管理和资源处理中。
3.1 BeanWrapper的装饰
BeanWrapper是Spring中用于操作Bean属性的强大工具,它通过装饰器模式增强了基本的属性访问功能。
关键类:
org.springframework.beans.BeanWrapperorg.springframework.beans.BeanWrapperImpl
public class BeanWrapperImpl implements BeanWrapper {
private Object wrappedObject;
private BeanWrapper nestedBeanWrapper;
public BeanWrapperImpl(Object wrappedObject) {
this.wrappedObject = wrappedObject;
}
@Override
public Object getWrappedInstance() {
return this.wrappedObject;
}
@Override
public Class<?> getWrappedClass() {
return (this.wrappedObject != null ? this.wrappedObject.getClass() : null);
}
@Override
public void setPropertyValue(String propertyName, Object value)
throws BeansException {
// 装饰:添加类型转换、验证等功能
BeanValueHolder valueHolder = new BeanValueHolder(propertyName, value);
PropertyValue pv = new PropertyValue(propertyName, valueHolder);
setPropertyValue(pv);
}
@Override
public Object getPropertyValue(String propertyName)
throws BeansException {
// 装饰:添加缓存、类型转换等功能
PropertyTokenHolder tokens = getPropertyNameTokens(propertyName);
return getPropertyValue(tokens);
}
}
3.2 HttpServletResponseWrapper的装饰
在Spring MVC中,通过装饰器模式包装原生HttpServletResponse对象。
public class HttpServletResponseWrapper extends ServletResponseWrapper
implements HttpServletResponse {
private HttpServletResponse response;
public HttpServletResponseWrapper(HttpServletResponse response) {
super(response);
this.response = response;
}
@Override
public void addCookie(Cookie cookie) {
this.response.addCookie(cookie);
}
@Override
public String encodeURL(String url) {
return this.response.encodeURL(url);
}
// 可以在这里添加额外的装饰功能
public void setCustomHeader(String name, String value) {
this.response.setHeader(name, value);
}
}
装饰器模式的优势
- 灵活扩展:可以在运行时动态地添加或撤销功能
- 避免类爆炸:相比继承,装饰器模式可以避免产生大量子类
- 单一职责:每个装饰器只关注一个特定的功能
4. 工厂模式(Factory Pattern)
什么是工厂模式?
工厂模式提供了一种创建对象的最佳方式,在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
Spring中的应用
Spring框架本身就是一个大型的工厂,IoC容器就是工厂模式的典型应用。
4.1 BeanFactory(简单工厂+工厂方法)
BeanFactory是Spring容器的核心接口,负责管理和配置Bean。
关键类:
org.springframework.beans.factory.BeanFactoryorg.springframework.beans.factory.xml.XmlBeanFactoryorg.springframework.beans.factory.support.DefaultListableBeanFactory
// BeanFactory接口
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch);
boolean isTypeMatch(String name, Class<?> typeToMatch)
throws NoSuchBeanDefinitionException;
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
// DefaultListableBeanFactory实现
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType,
@Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 1. 检查缓存中是否有实例化的单例Bean
Object beanInstance = getSingleton(beanName);
if (beanInstance != null) {
return (T) beanInstance;
}
// 2. 获取BeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 3. 创建Bean实例
beanInstance = createBean(beanName, mbd, args);
return (T) beanInstance;
}
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
this.beanDefinitionMap.put(beanName, beanDefinition);
}
}
4.2 ApplicationContext(抽象工厂)
ApplicationContext是BeanFactory的扩展,提供了更多企业级特性。
// ApplicationContext接口
public interface ApplicationContext extends EnvironmentCapable,
ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
String getId();
String getApplicationName();
String getDisplayName();
long getStartupDate();
ApplicationContext getParent();
AutowireCapableBeanFactory getAutowireCapableBeanFactory();
}
// ClassPathXmlApplicationContext实现
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations,
boolean refresh,
@Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
@Override
protected Resource[] getConfigResources() {
return this.configLocations;
}
}
4.3 FactoryBean(工厂Bean)
FactoryBean是Spring中特殊的工厂Bean接口,用于创建复杂对象。
// FactoryBean接口
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
// 示例:使用FactoryBean创建复杂对象
public class ConnectionFactoryBean implements FactoryBean<Connection> {
private String url;
private String username;
private String password;
public void setUrl(String url) {
this.url = url;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public Connection getObject() throws Exception {
DriverManager.getConnection(url, username, password);
}
@Override
public Class<?> getObjectType() {
return Connection.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
配置文件中使用:
<bean id="connection" class="com.example.ConnectionFactoryBean">
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
工厂模式的优势
- 解耦:将对象的创建和使用分离
- 灵活:可以方便地切换不同的实现
- 统一管理:集中管理对象的创建逻辑
- 可扩展:容易扩展新的产品类型
总结
Spring框架通过对设计模式的巧妙运用,实现了高度的可扩展性和灵活性:
| 设计模式 | Spring应用场景 | 核心类 |
|---|---|---|
| 代理模式 | AOP实现、事务管理 | JdkDynamicAopProxy、CglibAopProxy |
| 适配器模式 | MVC Handler适配、AOP Advice适配 | HandlerAdapter、AdvisorAdapter |
| 装饰器模式 | BeanWrapper、HttpServletResponseWrapper | BeanWrapperImpl、HttpServletResponseWrapper |
| 工厂模式 | IoC容器、Bean创建 | BeanFactory、ApplicationContext、FactoryBean |
学习Spring源码中的设计模式应用,不仅能帮助我们更好地理解Spring框架的工作原理,更能提升我们自身的代码设计能力。在实际开发中,我们应该根据具体场景选择合适的设计模式,避免过度设计。
参考资源
- Spring Framework官方文档
- 《Spring源码深度解析》
- 《设计模式:可复用面向对象软件的基础》
评论区