当前位置: 首页> 游戏> 评测 > 室内设计专业就业前景_用手机制作游戏的app软件_淘宝指数查询工具_公司网站建设推广

室内设计专业就业前景_用手机制作游戏的app软件_淘宝指数查询工具_公司网站建设推广

时间:2025/7/13 18:07:55来源:https://blog.csdn.net/u012453843/article/details/147076999 浏览次数:0次
室内设计专业就业前景_用手机制作游戏的app软件_淘宝指数查询工具_公司网站建设推广

一、单例模式        

         首先要说的便是单例模式,单例模式大家都知道目的是为了确保一个类只有一个实例,在spring中,我们就拿最典型的三级缓存来说明吧。

         我们看下spring中DefaultSingletonBeanRegistry类中的getSingleton方法的源码,如下所示,相信看了代码中的详细说明可以很清楚的知道单例模式在spring中用三级缓存解决循环依赖的用处了。

protected Object getSingleton(String beanName, boolean allowEarlyReference) {// Quick check for existing instance without full singleton lock//singletonObjects这个是第一级缓存,这个缓存里面存放的是已经准备就绪的bean//先根据beanName从第一级缓存中找,如果找到直接返回第一级缓存中缓存的bean。Object singletonObject = this.singletonObjects.get(beanName);//如果第一级缓存中没有找到对应的实例,并且发现这个bean目前正在创建中,还没有创建完成if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//这里就从第二级缓存中尝试获取,第二级缓存缓存的是半成品bean(实例化已完成但还未完成//初始化),如果第二级缓存中有这个bean,那么就直接返回半成品beansingletonObject = this.earlySingletonObjects.get(beanName);//如果第二级缓存里面也没有这个bean,并且允许早期引用(主要是为了解决循环依赖)if (singletonObject == null && allowEarlyReference) {//前两级缓存都没有,就要使用第三级缓存了,但使用前要先加锁,对第一级缓存加锁synchronized(this.singletonObjects) {// Consistent creation of early reference within full singleton lock//加锁成功后,为了避免重复创建对象,再次尝试从第一级缓存获取,有就直接返回singletonObject = this.singletonObjects.get(beanName);//如果第一级缓存中依然没有这个beanif (singletonObject == null) {//那么就接着从第二级缓存中尝试获取,有就直接返回singletonObject = this.earlySingletonObjects.get(beanName);//如果发现第二级缓存中还没有if (singletonObject == null) {//接着就从第三级缓存中获取到由创建bean所需元素组成的ObjectFactory//(这是一个lambda表达式)ObjectFactory <? > singletonFactory = this.singletonFactories.get(beanName);//如果第三级缓存中找到了这个bean进行实例化的信息if (singletonFactory != null) {//执行第三级缓存中的lambda表达式,从而创建bean实例singletonObject = singletonFactory.getObject();//将新创建的实例放入第二级缓存中(第二级缓存存的就是实例化完,//但还未初始化的半成品)this.earlySingletonObjects.put(beanName, singletonObject);//放入第二级缓存的同时,从第三级缓存中删掉该bean,这么做也是为//了避免重复创建bean的实例。也就是说第二级缓存和第三级缓存是//互斥的,而且都是在加锁的场景下操作的,这也就是为啥第一级缓存//用的是concurrenthashmap,而第二、第三级缓存用的是普通//的hashmap,因为人家都前提加锁了,再用线程安全的map也没啥意义。this.singletonFactories.remove(beanName);}}}}}}return singletonObject;
}

二、工厂模式

         先来简单说下什么是工厂模式,工厂模式是将对象的创建交由统一的工厂类来生成对象,避免直接在代码中硬编码具体类的实例化过程。它适用于需要灵活管理对象创建的场景,例如根据条件动态创建不同类型对象,隐藏对象创建的复杂性等。

       那么在spring中,工厂模式最典型的当然要数自动创建bean对象了,我们在类上加上@Component注解或@Resource等注解,spring就会帮我们去自动创建bean对象,不需要我们再手动专门new一个对象出来,下面我举spring中创建bean对象的一个关键方法来说明

       我们先来看下AbstractBeanFactory工厂类,也叫抽象工厂类,这个工厂类只提供了一个抽象方法,createBean,具体创建bean的过程由对应的子类来实现。

/*** Create a bean instance for the given merged bean definition (and arguments).* The bean definition will already have been merged with the parent definition* in case of a child definition.* <p>All bean retrieval methods delegate to this method for actual bean creation.* @param beanName the name of the bean* @param mbd the merged bean definition for the bean* @param args explicit arguments to use for constructor or factory method invocation* @return a new instance of the bean* @throws BeanCreationException if the bean could not be created*/
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException;

          AbstractAutowireCapableBeanFactory是AbstractBeanFactory的子类,这个从名字上就可以知道它也是一个工厂类,是管理spring bean生命周期的核心实现类,属于IoC容器的底层基础设施。它直接负责Bean的实例化、属性填充(依赖注入)、初始化方法调用等关键操作,是Spring实现依赖注入(DI)和自动装配(Autowiring)的核心引擎,如下图所示。

        这个类就实现了父类createBean的方法,如下所示,我们不做深入研究源码,而是重点看工厂模式的运用,这个方法最下面的那个try代码块中有一行是Object beanInstance = doCreateBean(beanName, mbdToUse, args);这是真正去创建bean对象的方法。

/*** Central method of this class: creates a bean instance,* populates the bean instance, applies post-processors, etc.* @see #doCreateBean*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.Class <? > resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();} catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}} catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}try {Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;} catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}
}

            doCreateBean方法源码如下,下面实例化、属性填充、初始化的地方我都用中文加了注释,也就是执行完这个方法后,我们写在项目里的实体类就被spring自动给创建好了,这省去了我们非常多的麻烦,让我们可以专心关注具体业务,而不用操心繁杂的bean创建过程。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {//这行代码是去创建bean的实例(但还未填充属性也未初始化)instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class <? > beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.synchronized(mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);} catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () - > getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {//这行代码是要填充bean属性(也就是依赖注入)populateBean(beanName, mbd, instanceWrapper);//这行代码是要对bean进行初始化,这里面包括初始化前Aware接口回调,初始化前置处理、初始化、初始化后置处理等动作exposedObject = initializeBean(beanName, exposedObject, mbd);} catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;} else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}}if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set < String > actualDependentBeans = new LinkedHashSet < > (dependentBeans.length);for (String dependentBean: dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);} catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;
}

三、代理模式

        首先说下什么是代理模式,它是通过创建一个代理对象来控制对原始对象(目标对象)的访问。代理对象在客户端和目标对象之间充当中介,可以在不修改目标对象代码的前提下,增强其功能(如添加日志、权限控制、加缓存等)。

        在spring中用到的代理分为两类,一类是JDK动态代理,这种针对的是是接口,如果目标对象实现了接口,那么就使用JDK动态代理。另一类是CGLIB代理,这种是目标对象没有实现接口。

        我们举个例子就比较清楚了,像下面这样,UserServiceImpl实现了UserService的接口,那么这种场景,spring就使用JDK动态代理来生成代理对象。

public interface UserService {void saveUser(User user);
}@Service
public class UserServiceImpl implements UserService {@Overridepublic void saveUser(User user) {// 数据库操作}
}

          而比如像我们下面的这个Student类,它只是加了@Component注解,而没有实现具体的接口,因此这个类在spring中就以CGLIB的代理模式创建代理对象。

package com.example.bean;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class Student {@Autowiredprivate Cource cource;private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}

四、策略模式

         首先说下什么是策略模式,策略模式是一种行为型设计模式,它定义了一系列算法(策略),并将每个算法封装成独立的类,使得它们可以相互替换。策略模式的核心思想是将算法的使用和算法的实现解耦,客户端可以根据需求动态选择不同的策略,而无需修改原有代码。

       那么在spring中哪些场景用到了策略模式呢?下面我们举两个最常用的例子

第一个:创建代理对象

策略接口:AopProxy

具体策略:

        JdkDynamicAopProxy:基于JDK动态代理生成接口代理。

       CglibAopProxy:基于CGLIB生成子类代理。

第二个例子:资源加载(ResourceLoader)

策略接口:ResourceLoader

具体策略:

       ClassPathResource:加载类路径资源。

       FileSystemResource:加载文件系统资源。

       UrlResource:加载网络资源(URL)

应用场景:根据资源路径前缀(如classpath:、file:)选择资源加载策略。

五、观察者模式

       首先说下什么是观察者模式,观察者模式是一种行为型设计模式,用于定义对象间的一对多依赖关系。当一个对象(称为主题或被观察者)的状态发生改变时,所有依赖它的对象(称为观察者)都会自动收到通知并更新自身状态。该模式的核心思想是解耦主题与观察者,使它们可以独立变化和扩展。

        观察者模式在spring中的应用,举个例子:bean的初始化与销毁回调

场景描述:Bean的初始化(如@PostConstruct)和销毁(如@PreDestry)通过事件机制触发,监听器执行回调逻辑。

源码实现:

        事件类型:BeanInitializationEventBeanDestructionEvent(内部事件,非直接暴露)。

        处理逻辑:InitDestroyAnnotationBeanPostProcessor 监听 Bean 的创建过程,解析 @PostConstruct 和 @PreDestroy 注解。

六、模板模式

        模板模式是一种行为型设计模式,用于定义一个操作中算法的骨架,将某些步骤的具体实现延迟到子类中去完成。它允许子类在不改变算法结构的情况下,重新定义某些步骤的实现。

       在spring中,使用模板模式的例子,像下面这个类,commit方法定义了事务的提交流程,提供了一个抽象方法doCommit(),交由实现具体的事务提交逻辑。

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager {@Overridepublic final void commit(TransactionStatus status) {// 固定流程:检查状态 → 处理回滚 → 触发同步 → 提交if (status.isCompleted()) {throw new IllegalTransactionStateException("事务已提交或回滚");}DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;if (defStatus.isLocalRollbackOnly()) {processRollback(defStatus, false);return;}if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {processRollback(defStatus, true);return;}processCommit(defStatus);  // 调用具体提交逻辑}// 抽象方法,由子类实现protected abstract void doCommit(DefaultTransactionStatus status);
}

          子类DataSourceTransactionManager为例,实现了doCommit方法,同时又可以利用父类的commit公共方法,这种就是模板模式的应用。

public class DataSourceTransactionManager extends AbstractPlatformTransactionManager {@Overrideprotected void doCommit(DefaultTransactionStatus status) {Connection con = status.getTransaction().getConnectionHolder().getConnection();try {con.commit();  // 实际提交事务(JDBC 实现)} catch (SQLException ex) {throw new TransactionSystemException("提交失败", ex);}}
}

关键字:室内设计专业就业前景_用手机制作游戏的app软件_淘宝指数查询工具_公司网站建设推广

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: