Spring-底层架构核心概念

这篇具有很好参考价值的文章主要介绍了Spring-底层架构核心概念。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Spring底层核心组件

BeanDefinition

BeanDefinition表示Bean定义,有很多属性用来描述Bean的特点:

  • class,表示Bean类型

  • scope,表示Bean作用域,单例或原型等

  • lazyInit:表示Bean是否是懒加载

  • initMethodName:表示Bean初始化时要执行的方法

  • destroyMethodName:表示Bean销毁时要执行的方法

  • 还有很多...

定义Bean的方式主要分为两种:

  • 申明式定义

    1、<bean/>
    2、@Bean
    3、@Component(@Service,@Controller)
  • 编程式定义

    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    
    // 生成一个BeanDefinition对象,并设置beanClass为User.class,并注册到ApplicationContext中
    AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
    beanDefinition.setBeanClass(User.class);
    beanDefinition.setScope("prototype"); // 设置作用域
    beanDefinition.setInitMethodName("init"); // 设置初始化方法
    beanDefinition.setLazyInit(true); // 设置懒加载
    
    context.registerBeanDefinition("user", beanDefinition);
    System.out.println(context.getBean("user"));

BeanDefinitionReader

BeanDefinition读取器,虽然开发中用的很少,但是源码中用得很多

AnnotatedBeanDefinitionReader

把某个类转换为BeanDefinition,并且解析类上的注解

AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(AppConfig.class);
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);
// 将User.class解析为BeanDefinition
annotatedBeanDefinitionReader.register(User.class);
System.out.println(context.getBean("user"));

可以解析的注解:@Conditional、@Scope、@Lazy、@Primary、@DependsOn、 @Role、@Description

XmlBeanDefinitionReader

解析<bean/>标签

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
System.out.println(context.getBean("user"));

ClassPathBeanDefinitionScanner

扫描器,可以进行扫描,扫描某个包路径,对扫描到的类进行解析

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("com.gax");
System.out.println(context.getBean("userService"));

BeanFactory

Bean工厂,负责创建Bean,并且提供获取Bean的 API

ApplicationContext就是BeanFactory的一种

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory,
HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
...
}

HierarchicalBeanFactory: 支持父子Bean工厂,子Bean工厂获取不到时,可以到父Bean工厂去获取
ListableBeanFactory: 展示Bean的名字、展示Bean的数量、统计的信息、拿某一个类型的Bean,类似列表的功能
EnvironmentCapable: 获取环境变量的功能
ApplicationEventPublisher: 事件发布的功能
MessageSource: 国际化的功能
ResourcePatternResolver: 获取某些资源、解析某些资源的功能

Spring源码中,BeanFactory接口非常重要的实现类: DefaultListableBeanFactory

ApplicationContext.getBean() 调用的就是 DefaultListableBeanFactory 的getBean()方法

DefaultListableBeanFactory 可以单独使用:

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);
beanFactory.registerBeanDefinition("user", beanDefinition);
System.out.println(beanFactory.getBean("user"));

ApplicationContext

ApplicationContext是个接口,实际上也是一个BeanFactory,不过比BeanFactory 更加强大:

1、HierarchicalBeanFactory:拥有获取父BeanFactory的功能

2、ListableBeanFactory:拥有获取beanNames的功能

3、ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)

4、EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)

5、ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)

6、MessageSource:拥有国际化功能

ApplicationContext两个重要的实现类:

1、AnnotationConfigApplicationContext

2、ClassPathXmlApplicationContext

国际化

定义一个MessageSource

@Bean
public MessageSource messageSource() {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("messages");
    return messageSource;
}

ApplicationContext拥有国际化的功能,可以直接用

context.getMessage("test", null, new Locale("en_CN"))

资源加载

可以利用ApplicationContext获取某个文件的内容

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

Resource resource = context.getResource("file://D:\\UserService.java");
System.out.println(resource.contentLength());
System.out.println(resource.getFilename());

Resource resource1 = context.getResource("https://www.baidu.com");
System.out.println(resource1.contentLength());
System.out.println(resource1.getURL());

Resource resource2 = context.getResource("classpath:spring.xml");
System.out.println(resource2.contentLength());
System.out.println(resource2.getURL());
                                        
Resource[] resources = context.getResources("classpath:com/gax/*.class");
for (Resource resource : resources) {
    System.out.println(resource.contentLength());
    System.out.println(resource.getFilename());
}

获取运行时环境

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

Map<String, Object> systemEnvironment = context.getEnvironment().getSystemEnvironment();
System.out.println(systemEnvironment); //操作系统层面的环境变量

Map<String, Object> systemProperties = context.getEnvironment().getSystemProperties();
System.out.println(systemProperties); //运行java通过-D指定的环境变量

MutablePropertySources propertySources = context.getEnvironment().getPropertySources();
System.out.println(propertySources); //最强大的,包含上面两种和PropertySources注解的变量

System.out.println(context.getEnvironment().getProperty("NO_PROXY")); //操作系统
System.out.println(context.getEnvironment().getProperty("sun.jnu.encoding")); //jvm -D指定
System.out.println(context.getEnvironment().getProperty("gax")); //property里面的

事件发布

定义一个事件监听器

@Bean
public ApplicationListener applicationListener() {
    return new ApplicationListener() {
        @Override
        public void onApplicationEvent(ApplicationEvent event) {
        	System.out.println("接收到了一个事件");
        }
    };
}

发布一个事件

context.publishEvent("yeah");

类型转化

Spring提供了一些方便类型转化的技术

PropertyEditor

JDK中提供的类型转化工具类,使用示例:

public class StringToUserPropertyEditor extends PropertyEditorSupport implements PropertyEditor
{
    @Override
    public void setAsText(String text) throws IllegalArgumentException
    {
        User user = new User();
        user.setName(text);
        this.setValue(user);
    }
    
    // 单独使用示例
    public static void main(String[] args)
    {
        StringToUserPropertyEditor propertyEditor = new StringToUserPropertyEditor();
        
        propertyEditor.setAsText("11");
        User value = (User)propertyEditor.getValue();
        System.out.println(value);
        System.out.println(value.getName());
    }
}

输出:
com.gax.service.User@5a07e868
11

向Spring中注册PropertyEditor:

@Bean
public CustomEditorConfigurer customEditorConfigurer()
{
    CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer();
    Map<Class<?>, Class<? extends PropertyEditor>> propertyEditorMap = new HashMap<>();
    // StringToUserPropertyEditor可以将String转化成User类型,
    // 在Spring源码中,如果当前对象是String,而需要的类型是User,就会用该PropertyEditor做类型转化
    propertyEditorMap.put(User.class, StringToUserPropertyEditor.class);
    customEditorConfigurer.setCustomEditors(propertyEditorMap);
    return customEditorConfigurer;
}

// 示例代码
@Component
public class UserService
{
    @Value("ccc")
    private User user; //这里需要类型转换
    
    public void test()
    {
        System.out.println(user);
    }
}

// 测试
public class Test 
{
	public static void main(String[] args) 
	{

		// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

		UserService userService = (UserService) applicationContext.getBean("userService");
		userService.test();
	}
}

输出:(输出的是一个User,转换成功)
com.gax.service.User@17ed40e0
ConversionService

Spring中提供的类型转化服务,它比PropertyEditor更强大

public class StringToUserConverter implements ConditionalGenericConverter
{
    @Override
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType)
    {
        return sourceType.getType().equals(String.class) && targetType.getType().equals(User.class);
    }
    
    @Override
    public Set<GenericConverter.ConvertiblePair> getConvertibleTypes()
    {
        return Collections.singleton(new GenericConverter.ConvertiblePair(String.class, User.class));
    }
    
    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType)
    {
        User user = new User();
        user.setName((String)source);
        return user;
    }
}

// 单独使用
public class Test 
{
	public static void main(String[] args) 
	{
		DefaultConversionService conversionService = new DefaultConversionService();
		conversionService.addConverter(new StringToUserConverter());
		User value = conversionService.convert("1", User.class);
		System.out.println(value);
	}
}

向Spring中注册ConversionService:

@Bean
public ConversionServiceFactoryBean conversionService()
{
    ConversionServiceFactoryBean conversionServiceFactoryBean = new ConversionServiceFactoryBean();
    conversionServiceFactoryBean.setConverters(Collections.singleton(new StringToUserConverter()));
    return conversionServiceFactoryBean;
}
TypeConverter

Spring提供更高级的转换类SimpleTypeConverter,可以支持上面两种

public class Test 
{
	public static void main(String[] args) 
	{
		SimpleTypeConverter typeConverter = new SimpleTypeConverter();
		typeConverter.registerCustomEditor(User.class, new StringToUserPropertyEditor());
//		DefaultConversionService conversionService = new DefaultConversionService();
//		conversionService.addConverter(new StringToUserConverter());
//		typeConverter.setConversionService(conversionService);
		User value = typeConverter.convertIfNecessary("1", User.class);
		System.out.println(value);
	}
}

扩展:

// getBean指定类型转换
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = applicationContext.getBean("userService", UserService.class);

// 可以对应到Spring源码:AbstractBeanFactory#adaptBeanInstance
<T> T adaptBeanInstance(String name, Object bean, @Nullable Class<?> requiredType) {
	// Check if required type matches the type of the actual bean instance.
	if (requiredType != null && !requiredType.isInstance(bean)) {
		try {
			// SimpleTypeConverter
			Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) { // 已经转换过了返回,没转换报错
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return (T) convertedBean;
		}
		catch (TypeMismatchException ex) {
			if (logger.isTraceEnabled()) {
				logger.trace("Failed to convert bean '" + name + "' to required type '" +
						ClassUtils.getQualifiedName(requiredType) + "'", ex);
			}
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	return (T) bean;
}

OrderComparator

Spring所提供的一种比较器,有@Order注解、实现Ordered接口两种使用方式,通过指定的值进行比较或排序。

实现Ordered接口示例代码:

public class A implements Ordered
{
    @Override
    public int getOrder()
    {
        return 3;
    }
    
    @Override
    public String toString()
    {
        return this.getClass().getSimpleName();
    }
}

public class B implements Ordered
{
    @Override
    public int getOrder()
    {
        return 2;
    }
    
    @Override
    public String toString()
    {
        return this.getClass().getSimpleName();
    }
}

public class Main
{
    public static void main(String[] args)
    {
        A a = new A(); // order=3
        B b = new B(); // order=2
        OrderComparator comparator = new OrderComparator();
        System.out.println(comparator.compare(a, b)); // 1 (a>b,a<b时返回-1)
        List list = new ArrayList<>();
        list.add(a);
        list.add(b);
        // 按order值升序排序
        list.sort(comparator);
        System.out.println(list); // B,A
    }
}

输出:
1
[B, A]

Spring还提供了一个OrderComparator的子类: AnnotationAwareOrderComparator,它支持用@Order来指定order值

@Order(3)
public class A
{
    @Override
    public String toString()
    {
        return this.getClass().getSimpleName();
    }
}

@Order(2)
public class B
{
    @Override
    public String toString()
    {
        return this.getClass().getSimpleName();
    }
}

public class Main
{
    public static void main(String[] args)
    {
        A a = new A(); // order=3
        B b = new B(); // order=2
		AnnotationAwareOrderComparator comparator = new AnnotationAwareOrderComparator();
        System.out.println(comparator.compare(a, b)); // 1
        List list = new ArrayList<>();
        list.add(a);
        list.add(b);
        // 按order值升序排序
        list.sort(comparator);
        System.out.println(list); // B,A
    }
}

输出:
1
[B, A]


// 关键源码:AnnotationAwareOrderComparator#findOrder
protected Integer findOrder(Object obj) {
    // 先获取Ordered接口中getOrder()方法返回的数值
    Integer order = super.findOrder(obj);
    if (order != null) {
        return order;
    }
    // 如果没有实现Ordered接口,则获取@Order注解中指定的值
    return findOrderFromAnnotation(obj);
}

BeanPostProcessor

BeanPostProcess表示Bean的后置处理器,可以定义一个或多个BeanPostProcessor

@Component
public class GaxBeanPostProcessor implements BeanPostProcessor 
{
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) 
	{
        if ("userService".equals(beanName)) 
		{
            System.out.println("初始化前");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) 
	{
        if ("userService".equals(beanName)) 
		{
            System.out.println("初始化后");
        }
        return bean;
    }
}

BeanPostProcessor可以在任意一个Bean的初始化之前以及初始化之后去额外的做一些用户自定义的逻辑,当然还可以通过判断beanName来进行针对性处理(针对某个Bean,或某部分Bean)。

我们可以通过定义BeanPostProcessor来干涉Spring创建Bean的过程

BeanFactoryPostProcessor

Bean工厂的后置处理器,和BeanPostProcessor类似。

BeanPostProcessor是干涉Bean的创建过程,BeanFactoryPostProcessor是干涉BeanFactory的创建过程。

@Component
public class GaxBeanFactoryPostProcessor implements BeanFactoryPostProcessor
{
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
    {
        System.out.println("加工beanFactory");
    }
}

FactoryBean

上面提到,可以通过BeanPostPorcessor来干涉Spring创建Bean的过程。但是如果我们想一个Bean完完全全由我们来创造,也是可以的,比如通过FactoryBean:

@Component
public class GaxFactoryBean implements FactoryBean
{
    @Override
    public Object getObject()
    {
        return new UserService();
    }
    
    @Override
    public Class<?> getObjectType()
    {
        return UserService.class;
    }
}

// 测试
public class Test
{
    public static void main(String[] args) throws IOException
    {
        // 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
		Object gaxFactoryBean = applicationContext.getBean("gaxFactoryBean");
		Object gaxFactoryBean2 = applicationContext.getBean("&gaxFactoryBean");
		Object gaxFactoryBean3 = applicationContext.getBean("&&&&&&gaxFactoryBean");
		System.out.println(gaxFactoryBean);
		System.out.println(gaxFactoryBean2);
		System.out.println(gaxFactoryBean3);
	}
}

输出:
com.gax.service.UserService@6e3c1e69
com.gax.GaxFactoryBean@5f150435
com.gax.GaxFactoryBean@5f150435

注意:通过这种方式创造出来的UserService的Bean,只会经过初始化后,其他Spring的生命周期步骤是不会经过的,比如依赖注入。

通过@Bean也可以生成一个对象作为Bean,那么和FactoryBean的区别是什么呢?

其实在很多场景下他俩是可以替换的,但是站在原理层面来说的,区别很明显,@Bean定义的Bean是会经过完整的Bean生命周期的。

ExcludeFilter和IncludeFilter

ExcludeFilter表示排除过滤器,IncludeFilter表示包含过滤器

// 扫描com.gax这个包下面的所有类,但是排除UserService类
// 也就是就算类上面有@Component注解也不会成为Bean
@ComponentScan(value = "com.gax", excludeFilters = {
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)})
public class AppConfig {
}

// 就算UserService类上没有@Component注解,也会被扫描成为一个Bean
@ComponentScan(value = "com.gax", includeFilters = {
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)})
public class AppConfig {
}

FilterType分为:

1、ANNOTATION:是否包含某个注解

2、ASSIGNABLE_TYPE:是否是某个类

3、ASPECTJ:是否符合某个Aspectj表达式

4、REGEX:是否符合某个正则表达式

5、CUSTOM:自定义

Spring内部怎么支持@Component注解扫描的?

在Spring的扫描逻辑中,默认会添加一个AnnotationTypeFilter给includeFilters,表示默认情况下 Spring扫描过程中会认为类上有@Component注解的就是Bean。

// ClassPathScanningCandidateComponentProvider#registerDefaultFilters
protected void registerDefaultFilters() {

	// 注册@Component对应的AnnotationTypeFilter
	this.includeFilters.add(new AnnotationTypeFilter(Component.class));

	... ...
}

MetadataReader、ClassMetadata、 AnnotationMetadata

在Spring中需要去解析类的信息,比如类名、类中的方法、类上的注解,这些都可以称之为类的元数 据,所以Spring中对类的元数据做了抽象,并提供了一些工具类。

public interface MetadataReader {

	/**
	 * Return the resource reference for the class file.
	 */
	Resource getResource();

	/**
	 * Read basic class metadata for the underlying class.
	 */
	ClassMetadata getClassMetadata();

	/**
	 * Read full annotation metadata for the underlying class,
	 * including metadata for annotated methods.
	 */
	AnnotationMetadata getAnnotationMetadata();
}

// 类的元数据
public interface ClassMetadata {

	/**
	 * Return the name of the underlying class.
	 */
	String getClassName();

	/**
	 * Return whether the underlying class represents an interface.
	 */
	boolean isInterface();

	/**
	 * Return whether the underlying class represents an annotation.
	 * @since 4.1
	 */
	boolean isAnnotation();

	/**
	 * Return whether the underlying class is marked as abstract.
	 */
	boolean isAbstract();

	/**
	 * Return whether the underlying class represents a concrete class,
	 * i.e. neither an interface nor an abstract class.
	 */
	default boolean isConcrete() {
		return !(isInterface() || isAbstract());
	}

	... ...
}

// 注解元数据
public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata {

	/**
	 * Get the fully qualified class names of all annotation types that
	 * are <em>present</em> on the underlying class.
	 * @return the annotation type names
	 */
	default Set<String> getAnnotationTypes() {
		return getAnnotations().stream()
				.filter(MergedAnnotation::isDirectlyPresent)
				.map(annotation -> annotation.getType().getName())
				.collect(Collectors.toCollection(LinkedHashSet::new));
	}
    
    /**
	 * Determine whether an annotation of the given type is <em>present</em> on
	 * the underlying class.
	 * @param annotationName the fully qualified class name of the annotation
	 * type to look for
	 * @return {@code true} if a matching annotation is present
	 */
	default boolean hasAnnotation(String annotationName) {
		return getAnnotations().isDirectlyPresent(annotationName);
	}

	/**
	 * 可以判断类下面有没有指定注解,比如说判断一个类下面有没有@Bean修饰的方法
	 * Determine whether the underlying class has an annotation that is itself
	 * annotated with the meta-annotation of the given type.
	 * @param metaAnnotationName the fully qualified class name of the
	 * meta-annotation type to look for
	 * @return {@code true} if a matching meta-annotation is present
	 */
	default boolean hasMetaAnnotation(String metaAnnotationName) {
		return getAnnotations().get(metaAnnotationName,
				MergedAnnotation::isMetaPresent).isPresent();
	}

	... ...
}

MetadataReader表示类的元数据读取器,默认实现类为SimpleMetadataReader

public class Test
{
    public static void main(String[] args) throws IOException
    {
        SimpleMetadataReaderFactory simpleMetadataReaderFactory = new SimpleMetadataReaderFactory();
        // 构造一个MetadataReader
        MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("com.gax.service.UserService");
        // 得到一个ClassMetadata,并获取了类名
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        System.out.println(classMetadata.getClassName());
        // 获取一个AnnotationMetadata,并获取类上的注解信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        for (String annotationType : annotationMetadata.getAnnotationTypes())
        {
            System.out.println(annotationType);
        }
	}
}

输出:
com.gax.service.UserService
org.springframework.stereotype.Component

注意:SimpleMetadataReader去解析类时,使用的ASM技术。

ASM简述:把类当成普通文件,通过字节流读出来,如果符合字节码规范,就根据字节码的格式获取类的信息

为什么要使用ASM技术?

Spring启动的时候需要去扫描,如果指定的包路径比较宽泛,那么扫描的类是非常多的,那如果在Spring启动时就把这些类全部加载进JVM了,这样不太好,所以使用了 ASM技术文章来源地址https://www.toymoban.com/news/detail-715041.html

到了这里,关于Spring-底层架构核心概念的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring底层核心架构

    相关的配置类 1. user类 2. AppConfig类 3.spring.xml class,表示Bean类型 scope,表示Bean作用域,单例或原型等 lazyInit:表示Bean是否是懒加载 initMethodName:表示Bean初始化时要执行的方法 destroyMethodName:表示Bean销毁时要执行的方法 还有很多… (1)BeanDefinition简单使用 说明:AbstractBean

    2024年02月12日
    浏览(42)
  • 【Spring】Spring底层核心原理解析

    简单代码: spring.xml内容: AppConfig.class内容: AppConfig.class替代了spring.xml文件,表示spring的配置文件; ApplicationContext在Spring、SpringMVC、SpringBoot中的创建方式: Spring,通过 ClassPathXmlApplicationContext 创建; SpringMVC,通过 XmlWebApplicationContext 创建; SpringBoot,通过 AnnotationConfigAppl

    2024年02月15日
    浏览(34)
  • Spring - Spring底层核心原理解析

    1. Bean的生命周期底层原理 2. 依赖注入底层原理 3. 初始化底层原理 4. 推断构造方法底层原理 5. AOP底层原理 6. Spring事务底层原理 对于这三行代码应该,大部分同学应该都是比较熟悉,这是学习Spring的hello world。可是,这三行代码底层都做了什么,比如: 第一行代码,会构造一

    2024年02月07日
    浏览(48)
  • 【Spring专题】Spring底层核心原理解析

    Spring啊,可以说是我们大部分Java玩家【最熟悉的陌生人】了吧。八个字形容:似懂非懂,会也不会 你说简单应用,我们大家都会,那真要展开说两句的话,那只能来这么两句:这是第一句,接着是第二句,好了我说完了。 但是啊xdm, 据说Spring是一份非常非常非常优秀的源码

    2024年02月13日
    浏览(47)
  • 走进Spring的世界 —— Spring底层核心原理解析(一)

    这是学习Spring的hello world。可是,这三行代码底层都做了什么,比如: 第一行代码,会构造一个ClassPathXmlApplicationContext对象,ClassPathXmlApplicationContext该如何理解,调用该构造方法除开会实例化得到一个对象,还会做哪些事情? 第二行代码,会调用ClassPathXmlApplicationContext的ge

    2024年02月07日
    浏览(55)
  • Spring概述与核心概念学习 -- Spring入门(一)

    为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。 (博客的参考源码以及可以在我主页的资源里找到,如果在学

    2024年02月16日
    浏览(47)
  • Spring源码系列:核心概念解析

    本文旨在为读者解析Spring源码中的关键类,以便读者在深入阅读源码时,能够了解关键类的作用和用途。在阅读Spring源码时,经常会遇到一些不熟悉的概念,了解关键类的作用可以帮助读者更好地理解这些概念。 BeanDefinition是Spring框架中的一个重要概念,它定义了一个Bean的基

    2023年04月20日
    浏览(47)
  • Spring 核心概念之一 IoC

    欢迎来到本篇文章!通过上一篇什么是 Spring?为什么学它?的学习,我们知道了 Spring 的基本概念,知道什么是 Spring,以及为什么学习 Spring。 今天,这篇就来说说 Spring 中的核心概念之一 IoC。 IoC 这个概念对于初学者来说还真不是很好理解,我就是那个理解不了的初学者。

    2024年02月07日
    浏览(37)
  • 深入解析Spring基本概念和核心思想

    使用spring后,被spring管理的类,不需要再new。 要想类被spring管理,则需要通过bean的方式,把类引入到spirng的配置文件中。 Ioc容器 简单的理解就是: 实现IoC思想,并提供对象创建,对象装配以及对象生命周期管理的软件就是Ioc容器 IoC理解 应用程序无需主动new对象,而是描述

    2024年02月12日
    浏览(46)
  • 深入浅出 Spring:核心概念和基本用法详解

    个人主页:17_Kevin-CSDN博客 收录专栏;《Java》 在 Java 企业级应用开发中,Spring 框架已经成为了事实上的标准。它提供了一种轻量级的解决方案,使得开发者能够更轻松地构建灵活、可扩展的应用程序。在本文中,我们将探讨 Spring 框架的一些核心概念和基本用法,以此更好地

    2024年03月20日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包