当前位置: 首页 > news >正文

长春做网站建设的公司开发者选项

长春做网站建设的公司,开发者选项,网站开发答辩难点,永久免费空间网站Spring底层核心组件 BeanDefinition BeanDefinition表示Bean定义#xff0c;有很多属性用来描述Bean的特点#xff1a; class#xff0c;表示Bean类型 scope#xff0c;表示Bean作用域#xff0c;单例或原型等 lazyInit#xff1a;表示Bean是否是懒加载 initMethod…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);MapString, Object systemEnvironment context.getEnvironment().getSystemEnvironment(); System.out.println(systemEnvironment); //操作系统层面的环境变量MapString, 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() {Overridepublic void onApplicationEvent(ApplicationEvent event) {System.out.println(接收到了一个事件);}}; } 发布一个事件 context.publishEvent(yeah); 类型转化 Spring提供了一些方便类型转化的技术 PropertyEditor JDK中提供的类型转化工具类使用示例 public class StringToUserPropertyEditor extends PropertyEditorSupport implements PropertyEditor {Overridepublic 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.User5a07e868 11 向Spring中注册PropertyEditor Bean public CustomEditorConfigurer customEditorConfigurer() {CustomEditorConfigurer customEditorConfigurer new CustomEditorConfigurer();MapClass?, 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.User17ed40e0 ConversionService Spring中提供的类型转化服务它比PropertyEditor更强大 public class StringToUserConverter implements ConditionalGenericConverter {Overridepublic boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType){return sourceType.getType().equals(String.class) targetType.getType().equals(User.class);}Overridepublic SetGenericConverter.ConvertiblePair getConvertibleTypes(){return Collections.singleton(new GenericConverter.ConvertiblePair(String.class, User.class));}Overridepublic 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 {// SimpleTypeConverterObject 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 {Overridepublic int getOrder(){return 3;}Overridepublic String toString(){return this.getClass().getSimpleName();} }public class B implements Ordered {Overridepublic int getOrder(){return 2;}Overridepublic String toString(){return this.getClass().getSimpleName();} }public class Main {public static void main(String[] args){A a new A(); // order3B b new B(); // order2OrderComparator comparator new OrderComparator();System.out.println(comparator.compare(a, b)); // 1 (ab,ab时返回-1)List list new ArrayList();list.add(a);list.add(b);// 按order值升序排序list.sort(comparator);System.out.println(list); // BA} }输出 1 [B, A] Spring还提供了一个OrderComparator的子类 AnnotationAwareOrderComparator它支持用Order来指定order值 Order(3) public class A {Overridepublic String toString(){return this.getClass().getSimpleName();} }Order(2) public class B {Overridepublic String toString(){return this.getClass().getSimpleName();} }public class Main {public static void main(String[] args){A a new A(); // order3B b new B(); // order2AnnotationAwareOrderComparator comparator new AnnotationAwareOrderComparator();System.out.println(comparator.compare(a, b)); // 1List list new ArrayList();list.add(a);list.add(b);// 按order值升序排序list.sort(comparator);System.out.println(list); // BA} }输出 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 {Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {if (userService.equals(beanName)) {System.out.println(初始化前);}return bean;}Overridepublic 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 {Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory){System.out.println(加工beanFactory);} } FactoryBean 上面提到可以通过BeanPostPorcessor来干涉Spring创建Bean的过程。但是如果我们想一个Bean完完全全由我们来创造也是可以的比如通过FactoryBean Component public class GaxFactoryBean implements FactoryBean {Overridepublic Object getObject(){return new UserService();}Overridepublic 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.UserService6e3c1e69 com.gax.GaxFactoryBean5f150435 com.gax.GaxFactoryBean5f150435 注意通过这种方式创造出来的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对应的AnnotationTypeFilterthis.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 empresent/em on the underlying class.* return the annotation type names*/default SetString 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 empresent/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();// 构造一个MetadataReaderMetadataReader 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技术
http://www.pierceye.com/news/168893/

相关文章:

  • 免费自己制作网站教程网站文字格式
  • 模板建站教程网站建设公司特色
  • 广州网站设计制作江门住房与城乡建设局官方网站
  • 电子商城网站建设参考文献新手建立企业网站流程
  • 站长工具使用wordpress搜索框制作教程
  • 上海翼成信息科技有限公司做的什么网站怎么办一个网站
  • 上海网站建设的英文wordpress login 图标
  • 雅安市网站建设搭建网站工具
  • 网站如何做301重定向南宁一站网 给网站做营销
  • 网站 使用的字体女生电子商务专业适合做什么
  • 电商网站首页模板连云港 网站 建设
  • 自助建站广告发布企业年检网上申报流程
  • 河北平台网站建设价位外包网站有哪些
  • 做网站客户需要提供的资料梧州网站建设推荐
  • 网站商城建设实训心得网络推广有用吗
  • 考试网站建设房价2024年暴跌
  • 北京网站seo价格建设教育培训的网站
  • 怎样做网站手机和电脑通用木马工业设计公司
  • 榆林市建设局官方网站ppt中网站布局图怎么做
  • 网站视频插件代码如何创建自己的软件
  • 如何免费建造网站电商网站建设哪家好
  • ps做网站首页设计教程郑州seo优化外包热狗网
  • 给网站增加功能怎么做360搜索关键词优化软件
  • 如何做公司网站空间南昌做网站的公司哪个比较好的
  • 美容网站开发网络营销的功能有哪些
  • 推广自己的网站需要怎么做做政协网站的目的是什么
  • 综合性电子商务网站有哪些商城系统软件开发
  • 网站服务器解决方案企业门户网站管理要求
  • 南京网站开发南京乐识专注岳阳网站建设网站
  • 做一直播网站要多少钱淘宝客如何建设推广网站