当前位置: 首页 >  业内资讯  >   >  正文

【Spring源码】- 04 扩展点之BeanFactoryPostProcessor

  • 2023-03-28 21:29:33 来源:腾讯云

之前分析IoC容器的启动流程时,夹杂在启动流程中我们发现Spring给我们提供了大量的扩展点,基于这些扩展点我们就可以实现很多灵活的功能定制需求。这篇我们首先来看下BeanFactoryPostProcessor这个扩展点,它是非常重要的一个扩展点,面向IoC容器进行扩展。

类结构

BeanFactoryPostProcessorBeanFactory的后置处理器,针对BeanFactory实现各种功能扩展。BeanFactoryPostProcessor又分为两类:BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessorBeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,对其进行了扩展。

执行时机

前面分析IoC容器启动流程中,refresh()方法中invokeBeanFactoryPostProcessors(beanFactory)处触发BeanFactoryPostProcessor扩展类的执行。


(资料图片仅供参考)

执行逻辑总结:1、先执行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法,其中BeanDefinitionRegistryPostProcessor执行优先级如下:a、addBeanFactoryPostProcessor()传入到优先级最高,因为不需要实例化,直接可以获取到对象进行执行; b、然后从IoC容器中获取PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,实例化并排序后执行postProcessBeanDefinitionRegistry方法 c、然后从IoC容器中获取Ordered接口的BeanDefinitionRegistryPostProcessor,实例化并排序后执行postProcessBeanDefinitionRegistry方法 d、然后从IoC容器中获取剩余的BeanDefinitionRegistryPostProcessor,实例化后执行postProcessBeanDefinitionRegistry方法;注意这个处理步骤存在一个循环,主要是存在执行前面的BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法时,存在可能会向IoC容器中注册新的BeanDefinitionRegistryPostProcessor,通过循环保证都会被执行;2、然后执行BeanDefinitionRegistryPostProcessor#postProcessBeanFactory方法,执行顺序参照步骤1中执行顺序;3、最后才会执行BeanFactoryPostProcessor#postProcessBeanFactory,执行优先级和BeanDefinitionRegistryPostProcessor一致: a、addBeanFactoryPostProcessor()传入到优先级最高,因为不需要实例化,直接可以获取到对象进行执行; b、然后从IoC容器中获取PriorityOrdered接口的BeanFactoryPostProcessor,实例化并排序后执行postProcessBeanFactory方法 c、然后从IoC容器中获取Ordered接口的BeanFactoryPostProcessor,实例化并排序后执行postProcessBeanFactory方法 d、然后从IoC容器中获取剩余的BeanFactoryPostProcessor,实例化后执行postProcessBeanFactory方法

总结两句话:

1、不同方法执行优先级:`BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry` > `BeanDefinitionRegistryPostProcessor#postProcessBeanFactory` > `BeanFactoryPostProcessor#postProcessBeanFactory`;
2、同方法执行优先级:`addBeanFactoryPostProcessor` > `PriorityOrdered` > `Ordered` > 非排序

使用场景

这两个接口都比较简单,都只定义一个方法。首先看下BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry这个方法,主要使用场景是:向IoC容器中注册BeanDefinition。这里面有个非常重要的实现类:ConfigurationClassPostProcessor,完成各种将Bean解析成BeanDefinition注入到IoC容器功能。

BeanDefinitionRegistryPostProcessor

案例一

首先,我们来看个例子,自定义BeanDefinition方式注册到IoC容器中。

1、定义一个Bean

public class TestService02 { private TestService01 testService01; @Autowired private TestService03 testService03; private String name;     //省略setter、toString方法}

2、由于该Bean没有@Component等注解,所以我们可以定义一个BeanDefinitionRegistryPostProcessor扩展注册到IoC容器中:

@Componentpublic class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {  System.out.println("===MyBeanFactoryPostProcessor#postProcessBeanDefinitionRegistry===");  //创建一个BeanDefinition  RootBeanDefinition beanDefinition = new RootBeanDefinition(TestService02.class);  //获取MutablePropertyValues,用于添加依赖注入  MutablePropertyValues pvs = beanDefinition.getPropertyValues();  //为依赖注入指定固定值方式  pvs.addPropertyValue("name", "张三");  //为依赖注入指定beanName,自动将beanName指向IoC中的Bean注入进去  pvs.addPropertyValue("testService01", new RuntimeBeanReference("testService01"));  //将生成的BeanDefinition注册到IoC容器中  registry.registerBeanDefinition("testService02", beanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {  System.out.println("===MyBeanFactoryPostProcessor#postProcessBeanFactory==="); }}

3、输出结果:

myConfigtestService01testService03myBeanFactoryPostProcessortestService02===TestService02属性信息===TestService02{testService01=xxx.bean.TestService01@56ef9176, testService03=xxx.bean.TestService03@4566e5bd, name="张三"}

从输出结果可以看到,TestService02已被注册到IoC容器中,且其属性字段都已成功进行依赖注入。通过这种方式,我们就可以更加灵活的向IoC容器注册Bean,实现各种功能的扩展。

案例二

我们可以模拟@ComponentScan@Component注解方式实现:将指定路径下的带有指定注解的Bean注册到IoC容器中。

1、首先,模仿@ComponentScan@Component定义两个注解:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Indexedpublic @interface MyComponent { String value() default "";}
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Documentedpublic @interface MyComponentScan { @AliasFor("basePackages") String[] value() default {}; @AliasFor("value") String[] basePackages() default {}; Class[] basePackageClasses() default {};}

2、定义一个BeanDefinitionRegistryPostProcessor实现类:

@Componentpublic class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor { private List basePackageList = new ArrayList<>(); @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {  System.out.println("===MyBeanFactoryPostProcessor#postProcessBeanFactory==="); } @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {  Arrays.stream(registry.getBeanDefinitionNames()).forEach(x -> parseMyComponentScan(registry.getBeanDefinition(x)));  if(basePackageList.isEmpty()){//没有扫描路径情况   return;  }  //定义一个BeanDefinitionScanner,扫描指定路径下Bean  ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);  scanner.addIncludeFilter(new AnnotationTypeFilter(MyComponent.class));  scanner.setIncludeAnnotationConfig(false);  String[] basePackages = basePackageList.stream().toArray(String[]::new);  int beanCount = scanner.scan(basePackages);  System.out.println("注册成功:"+beanCount); } /**  * 遍历所有的BeanDefinition,然后解析出有@MyComponentScan注解信息,并提取basePackageClasses属性值,  * 解析成扫描路径存储到basePackageList集合中  * @param beanDefinition  */ private void parseMyComponentScan(BeanDefinition beanDefinition){  if(AnnotatedBeanDefinition.class.isAssignableFrom(beanDefinition.getClass())){   AnnotatedBeanDefinition bdf = (AnnotatedBeanDefinition) beanDefinition;   Class beanClass;   try {    beanClass = Class.forName(bdf.getBeanClassName());    AnnotationMetadata metadata = AnnotationMetadata.introspect(beanClass);    Map config = metadata.getAnnotationAttributes(MyComponentScan.class.getName());    if(config != null && config.containsKey("basePackageClasses")){     Object obj = config.get("basePackageClasses");     Class clz = ((Class[]) obj)[0];     basePackageList.add(clz.getPackage().getName());    }   } catch (Throwable e) {    e.printStackTrace();   }  } }}

3、测试:

@Configuration@ComponentScan(basePackageClasses = MyConfig.class)@MyComponentScan(basePackageClasses = MyConfig.class)public class MyConfig {}

@ComponentScan可以把常规的@Component注册到IoC容器中,@MyComponentScan可以把指定包路径下带有@MyComponent注解的Bean注册到IoC容器中。

BeanFactoryPostProcessor

上面我们利用BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry扩展方法实现了@MyComponentScan@MyComponent注解功能,实现将指定包路径下带有@MyComponent注解的Bean注册到IoC容器中。BeanDefinitionRegistryPostProcessor接口中还有一个继承父接口BeanFactoryPostProcessor中的方法:postProcessBeanFactory

上一个案例实现了@MyComponent注解的Bean注册到IoC功能,现在我们来实现对所有@MyComponent注解的类进行AOP增强。

1、定义一个增强类:

public class MyMethodInterceptor implements MethodInterceptor {    @Override    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy)            throws Throwable {        try {            before(method);//前置通知            Object ret = methodProxy.invokeSuper(obj, args);//目标方法执行            after(method, ret);//后置通知            return ret;        } catch (Exception e) {            exception();//异常通知        } finally {            afterReturning();//方法返回通知        }        return null;    } //前置增强    private void before(Method method) {        System.out.printf("before execute:%s\r\n", method.getName());    } //后置增强    private void after(Method method, Object ret) {        System.out.printf("after execute:%s, ret:%s\r\n", method.getName(), ret);    } //异常增强    private void exception() {        System.out.println("execute failure");    } //after返回增强    private void afterReturning() {        System.out.println("execute finish");    }}

2、基于Spring Enhancer工具类,实现一个传入Class,创建一个带有增强逻辑的Class返回出来工具类:

public class EnhancerUtil  { //定义增强实例 private static final Callback[] CALLBACKS = new Callback[] {   new MyMethodInterceptor(),   NoOp.INSTANCE }; private static final Class[] CALLBACKTYPES = new Class[] {   new MyMethodInterceptor().getClass(),   NoOp.INSTANCE.getClass() }; public static Class createProxyClass(Class targetClz){  Enhancer enhancer =  new Enhancer();  //基于继承方式代理:设置代理类的父类,就是目标对象,创建出来的对象就是目标对象的子类  enhancer.setSuperclass(targetClz);  //设置回调过滤器,返回值是callbacks数组的下标  enhancer.setCallbackFilter(new CallbackFilter() {   @Override   public int accept(Method method) {    /**     * 屏蔽掉Object类中定义方法的拦截     */    if (method.getDeclaringClass() == targetClz) {     return 0;    }    return 1;   }  });  /**   * NoOp回调把对方法调用直接委派给这个方法在父类中的实现,即可理解为真实对象直接调用方法   */  enhancer.setCallbackTypes(CALLBACKTYPES);  //设置类加载器  enhancer.setClassLoader(targetClz.getClassLoader());  //创建代理对象  Class clz = enhancer.createClass();  Enhancer.registerStaticCallbacks(clz, CALLBACKS);  return clz; }}

3、下面我们来实现BeanFactoryPostProcessor#postProcessBeanFactory方法:

@Componentpublic class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor { private List basePackageList = new ArrayList<>(); /**  * 基于该扩展实现AOP增强  * @param beanFactory  * @throws BeansException  */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {        //遍历IoC中BeanDefinition  Arrays.stream(beanFactory.getBeanDefinitionNames())    .forEach(x -> enhancer(beanFactory.getBeanDefinition(x))); }    /**  * 判断beanDefinition是否有@MyComponent注解,如果有则调用EnhancerUtil.createProxyClass创建一个增强后的类,  * 并替换到BeanDefinition中的beanClass  * @param beanDefinition  */ private void enhancer(BeanDefinition beanDefinition){  if(ScannedGenericBeanDefinition.class.isAssignableFrom(beanDefinition.getClass())){   ScannedGenericBeanDefinition bdf = (ScannedGenericBeanDefinition) beanDefinition;   try {    String beanClassName = bdf.getBeanClassName();    Class beanClass = Class.forName(beanClassName);    if (beanClass != null){     AnnotationMetadata metadata = AnnotationMetadata.introspect(beanClass);     if(metadata.hasAnnotation(MyComponent.class.getName())){      Class enhancedClass = EnhancerUtil.createProxyClass(beanClass);      if(enhancedClass != beanClass){       bdf.setBeanClass(enhancedClass);      }     }    }   } catch (Throwable e) {    e.printStackTrace();   }  } }}

4、定义Bean

@MyComponentpublic class TestService02 { public String hi(String name){  System.out.println("===TestService02#hi===");  return "hello,"+name; }}

5、context.getBean(TestService02.class).testService02.hi("zhangsan")调用方法时,会发现方法前后都已被加入增强逻辑:

before execute:hi===TestService02#hi===after execute:hi, ret:hello,zhangsanexecute finish返回结果:hello,zhangsan

总结

通过使用场景案例分析,我们对BeanFactoryPostProcessor扩展点的使用大致情况应该有了一些了解:

BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry这个扩展点主要用于实现向IoC容器中注册Bean相关的功能扩展。比如上面案例中我们九利用该扩展点实现了自定义扫描包路径下自定义注解,并向IoC容器中注册BeanBeanFactoryPostProcessor#postProcessBeanFactory这个扩展点主要用于实现将注册到IoC容器中BeanDefinition进行相关操作。以为这个方法执行时机是在postProcessBeanDefinitionRegistry之后,这时Bean都已经以BeanDefinition样式被注册到IoC容器中,这时就可以对这些BeanDefinition进行操作。比如案例中我们获取到BeanDefinition中的beanClass属性,并使用Enhancer工具类创建AOP代理类并设置进去,就实现了Spring中的AOP功能。

标签:

上一篇 :

下一篇 :

最新推荐

【Spring源码】- 04 扩展点之BeanFactoryPostProcessor

之前分析IoC容器的启动流程时,夹杂在启动流程中我们发现Spring给我们提供了大量的扩展点,基于这些扩展...

房屋中可能存在的不同种类的气体_送老人什么生日礼物比较好

霉菌、灰尘、皮屑和气体都会影响您家中的空气质量。有害气体可以从室外进入家中或由电器产生。家中通常...

融资丨「亚丁金融」完成数千万元A轮融资,斯道资本独家投资

融资丨「亚丁金融」完成数千万元A轮融资,斯道资本独家投资,本轮融资是亚丁首次进行外部融资

薛赢:低毛利下业绩增长新路径 环球时快讯

由全联冶金商会、冶金工业规划研究院、中国金属材料流通协会指导,中钢网与天津友发钢管集团联合主办的...

本周我要建仓的基金_环球动态

本周我要建仓的基金,基金,操盘,择机,etf,创业板

泰伦-卢确认巴图姆将取代莫里斯一直打首发

泰伦-卢确认巴图姆将取代莫里斯一直打首发,快船队,泰伦·卢,泰伦-卢,美国篮球,尼古拉·巴顿,国际篮球赛...

报告:苹果iPhone最保值 折旧率仅为安卓手机一半|全球即时

3月28日消息,根据BankMyCell发布的2021-2022年手机折旧报告显示,苹果iPhone手机最为保值,而同期安卓...

环球即时看!广西左江流域发现大型史前蛇类遗存 当地猎食蛇类史或达6000年

广西左江流域发现大型史前蛇类遗存当地猎食蛇类史或达6000年

强制执行都执行什么财产

一、强制执行都执行什么财产强制执行的财产包括:1 收入、银行存款、现金、有价证券;2 土地使用权、...

xiaomiflash刷机工具_xiaomiflash:每日头条

1、我可以教你我我可以发给你OfficeMiflash刷机教程。本文就为大家分享到这里,希望小伙伴们会喜欢。

天天即时看!使命召唤战区2卡顿掉帧怎么办 cod2战区卡顿问题解决方法

使命召唤战区2卡顿掉帧的情况出现时,可以先检查是否是因为后台程序开太多所导致的,可以先关闭后台程序...

集美区与吉安市永丰县签订合作协议 这些便民事项可实现"跨省通办"-环球即时

护士申请执业注册或延续注册,医师申请执业注册或注销注册,文艺表演团体《营业性演出许可证》申请延续...

看热讯:山东将推动形成五大主题旅游公路廊道

□记者吴荣欣报道本报威海讯记者从日前在威海召开的全省旅游公路建设推进会上获悉,我省将加快推进公路...

山东泰山新国脚霸气放话,表现获得称赞,新赛季锁定主力!_全球观焦点

最近一段时间,中超传统豪门球队山东泰山受到了很多球迷的关注。北京时间3月27日,山东泰山再次完成集结...

匈牙利议会投票通过芬兰加入北约的请求-今日要闻

据央视新闻,当地时间3月27日,匈牙利议会投票通过了芬兰加入北约的请求。来源:同花顺7x24快讯

稳居世界第一!姆巴佩身价不变,1.8亿欧仍为全球第一身价

直播吧3月27日讯今日德转更新了法甲的身价数据。巴黎的巨星姆巴佩本期身价不变,仍是去年12月的1 8亿,...

不出园区办政务 门头沟区首家园区政务服务站启用

新京报讯(记者周怀宗)准入准营、日常运营、变更注销……在中关村门头沟园,1600多项区级政务事项,不...

每日动态!2022款大指挥官用车记,车主开了1550公里后,说了实在话

大家好!我是大指挥官车主,来自宜宾,我提的车型是 "2022款2 0T四驱豪华版 ",购车价27万,开了1550公里,综

奥迪电动Q4大降价!只卖22.88万元 比大众ID.4便宜

奥迪电动Q4大降价!只卖22 88万元比大众ID 4便宜,指导价,同平台,电动车,奥迪q4,奥迪电动,大众id,e-tron

头部车企打架尾部车企“下架” 恒驰汽车北京线下门店仅1家营业

据朝阳区金港汽车公园门店工作人员介绍,目前店内有1万元定金抵2万元活动,如果选择17 9万元的裸配恒驰...

快手小店保证金每个月都交吗?要交多少钱?:世界时快讯

目前在快手平台上发表一些短视频,可以吸引到更多的粉丝量,这时候就能够进行带货,并且获得不错的效果...

【世界时快讯】坎塞洛:列士敦士登有很多也许球员,向他们的努力致...

坎塞洛:列士敦士登有很多也许球员,向他们的努力致敬3月24日讯今天凌晨,葡萄牙4-0击败列支敦士登,赛...

世界最新:陕西府谷县三道沟镇 以党建引领促进乡村振兴

中国农科新闻网是农业科技报社顺应网络时代新媒体发展趋势,在三农领域倾心打造的集资讯、互动、网上展...

全国排名第六,湖南向万亿级预制菜市场发起冲击_世界观天下

预制菜行业,一个万亿级的“蓝海”即将诞生。3月26日,由湖南省商务

周边商铺火了,居民却叫苦不迭,他们出手了……|快报

位于新天地商圈的淡水路,兼具市井烟火与小资情调。但是,一些沿街商铺中,个别存在店铺占道经营、油污...

【全球新要闻】拜登经济团队继续重组:白宫经济顾问委员会主席劳斯将于本月底离职

彭博3月26日消息,美国白宫经济顾问委员会主席塞西莉亚·劳斯(CeciliaRouse)确认将于当地时间3月31日离职

央地深化合作 内蒙古聚焦链主企业

近日,内蒙古自治区与中央企业深化合作座谈会暨招商引资(京津冀地区)推介及项目签约仪式在北京召开,...

手背上有小红点像血点不痛不痒_手背上有小红点是怎么回事

1、病情分析:手背有红点,可能由以下原因引起:一是过敏,可涂抹硝酸咪康唑乳膏,服用维生素C或氯雷他...

天天简讯:萨拉托夫国立技术大学_关于萨拉托夫国立技术大学的简介

1、萨拉托夫国立技术大学是俄罗斯伏尔加河地区乃至整个国家最大的教育和科学中心之一,在俄罗斯教育部对...

全球观速讯丨文化苦旅好段摘抄赏析300字(文化苦旅好段摘抄赏析)

1、向往巅峰,向往高度,结果巅峰只是一道刚能立足的狭地,不能横行,不能直走,只享一时俯视之乐,怎可...

山东加快推动由观光旅游向观光旅游和休闲度假旅游并重转变

3月26日,作为2023山东省旅游发展大会重要活动之一,2023国际旅游休闲城市·青岛论坛举办。

天天通讯!中国国际经济交流中心副理事长朱民:5%的经济增长目标是审慎、可持续的

转自:上海证券报上证报中国证券网讯(记者汤立斌)中国国际经济交流中心副理事长朱民25日在中国发展高...

全球快看点丨和平精英怎么免费领皮肤

1、登录游戏。2、在游戏人物主界面找到【军需】功能。3、切换到【金币军需】。4、通过得开启【金币军需...

谁有网址没封的_谁有网址

1、j姐姐我有绝对包你喜欢。本文就为大家分享到这里,希望小伙伴们会喜欢。

当前视点!黄梅“链”式招商做强大产业

黄梅“链”式招商做强大产业---今年1月,黄梅与以能源化工为主的国有特大型企业集团——中国平煤神马集...

简讯:四季常绿花卉图片大全_四季常绿花卉有哪些

1、宿根常绿耐阴多年生草本有:万年青、一叶兰、麦冬(麦门冬、沿阶草)、阔叶沿阶草(书带草)、葱莲(...

上嘴唇突然肿了是怎么回事啊_上嘴唇突然肿了是怎么回事

1、上唇突然肿了,医院口腔科要做口腔检查,拍x光。2、如果上前牙有明显龋坏并伴有牙龈明显肿胀,X线片...

晖怎么读

1、晖字读音:[huī]。2、释义:〈名〉形声。从日,军声。字本作“晕”。本义:日月周围的光圈。日色;阳光...

创始人原配之子接棒杉杉股份 继母表示反对 律师解读遗产谁继承-全球即时看

郑永刚离世后,“90后”郑驹接过父亲的担子,成为杉杉股份(600884 SH)的董事长。不过,郑驹的继母周婷...

储能概念板块重回涨势,碳酸锂价格跌破30万元大关

数据梳理并制表:焦艳丽  华夏时报记者焦艳丽陆肖肖北京报道  本周(3月20日—24日),储能概念板块...

股东户数最新变动:泛亚微透(688386)股东户数0.34万户,较上期增加6.75%

近日泛亚微透披露,截至2023年2月28日公司股东户数为3433 0户,较12月31日增加217 0户,增幅为6 75%...

什么是精准广告投放

定义:精准广告投放是指广告主在数字媒体交易平台、广告投放平台或者网络号系统平台上,选择特定的目标...

上海基层政府探索社区治理新模式:“星海造梦”计划汇聚“民智”“民力”

上海基层政府探索社区治理新模式:“星海造梦”计划汇聚“民智”“民力”---金海街道创新启动了“星海造...

今日热闻!信用卡持卡人死了还用还吗

需要偿还的。当信用卡持卡人死亡,信用卡的欠款依然需偿还,欠款则需由债权人的继承人来归还,当然这个...

全球观察:转型电动化,韩系车在中国还有救吗?

转型电动化,韩系车在中国还有救吗?,新车,韩系车,概念车,电动化,量产车,起亚汽车,新能源汽车

全球新资讯:appstore是干什么用的

APP指智能手机的第三方应用程序。AppStore是苹果战略转型的重要举措之一。AppStore模式的意义在于为第三...

小白鞋可以下岗了!今年爆火的阿甘鞋,平价不撞款,谁穿谁时髦~

天气回暖,很多人就开始物色新衣了~“穿合适的鞋子,走通天大道宽又阔的路”,你的鞋有没有也跟上日程?...

当前消息!rwby壁纸 手机壁纸_rwby壁纸

1、问题分类改到【娱乐休闲-动漫】处。2、再采纳。3、谢谢合作!!画师ASK作品PixivID:37472968。本

环球观焦点:股票行情快报:宏德股份(301163)3月24日主力资金净卖出67.19万元

截至2023年3月24日收盘,宏德股份(301163)报收于29 86元,下跌0 3%,换手率3 39%,成交量6916 0手,成交额2068 38万元。

速递!上海临港发布科创政策20条:聚焦全过程创新 最高支持1亿元

此间官方表示,本次发布的科创政策20条聚焦全过程创新,覆盖“0到1的源头创新”“1到10的创新加速”“10...

X 广告
X 广告

精彩放送

卡撒天娇(02223)发布2022年业绩,股东应占溢利537.8万港元,同比下降54.9%-天天头条

成都必去的10个景点

上海机场: 上海机场2022年度业绩快报公告|焦点快播

《大侠立志传》霖安城宝箱位置介绍:世界热闻

2023福建福州市鼓楼区国有资产投资发展有限公司招聘拟录用名单公示

人类一败涂地要钱吗_人类一败涂地要钱

【世界播资讯】华友钴业(603799):全解析系列之四:华友钴业六问六答

仙道枫为什么哭了

【环球速看料】赖声川创作艺术展 落地京城 观众将“沉浸式”穿梭于经典“赖式作品”场景中

中国科学家揭示作物在盐碱地增产的“基因密码”|新视野

天天亮点!云南武定牡丹文化旅游节3月25日启幕

金徽酒东出不利

被转移的夫妻共同财产分割应该如何解决,遇到这种情况怎么办:全球最新

环球最资讯丨太阳报:若指控成立曼联可能被罚7.5万镑,本赛季已被罚13.7万镑

广州出名的高中艺术学院 世界观察

2023’CNCE棉业发展年会在京召开 聚焦中国棉业高质量发展之路

《未来生活》主要人物介绍:天天报资讯

高德地图回应与口碑业务合并:有助于提供更好的到目的地服务-环球信息

《神雕侠侣》杨过最爱郭芙?金庸各种暗线,你看懂了吗?

王凯有女朋友吗 王凯宋茜要结婚了是真的吗

每日报道:后会无期徐良歌词

警惕帮信犯罪陷阱 避免沦为电诈帮凶

【聚看点】³´²èÀ²£¡½ü¾à¸ÐÊܶ¼ÔÈë¼â´º²è³´ÖÆ

全球快看:速派/柯迪亚克等 斯柯达2023新车规划曝光

浐灞三十三小节约用水主题教育活动

“出问题的材料已全部拆除”,上海内环内“千人摇”红盘,未建完就……

黑石深渊怎么去

香农芯创03月22日深股通持有量18.08万股_环球热推荐

热点聚焦:花甲暂时不吃怎样保存的_花甲当天不吃怎么存放

天天快播:Java循环运行时暂停一段时间

无缘无故的意思和造句_无缘无故的意思-环球新要闻

英雄联盟靠什么配置,玩LOL需要什么电脑配置_全球观天下

今日起,河南开展全面数字化的电子发票试点工作-世界头条

全球通讯!2023杭州临安半程马拉松青山湖景区交通管控措施一览

当日快讯:国家发改委:加快东北振兴重点项目建设

消息!蔚来汽车CFO:价格战说明中国车企太多了 但蔚来没有收购计划

“好险!我这5万元保住了!”:每日看点

当前短讯!熙菱信息3月22日快速回调

【世界聚看点】邮储银行回应储户243万存款被挪用具体详细内容是什么

三人行(605168):3月21日北向资金增持4.82万股

【世界热闻】智通全球财经日志|3月22日

OPPO Pad 2平板电脑宣布作为更名后的OnePlus Pad

环球新消息丨国际医学:公司旗下医院药品和耗材大部分已实现零加成,目前并未设立医疗器械公司

整数矩阵_关于整数矩阵简介_环球播报

工商银行喜结良缘金条50克价格今天多少一克(2023年03月21日)|天天看点

挤兑压力更大第一共和银行成监管第一关注对象

湖北黄冈黄梅县市场监管局“七个一”扎实开展春耕护农行动:热资讯

雌二醇怀孕早期正常值参考表_雌二醇怀孕早期的正常值

世界信息:苏博特(603916):3月20日北向资金增持13.42万股

氟哌酸能治疗牙髓炎吗_氟哌酸治疗尿道炎用法

Copyright ©  2015-2022 世界律师网版权所有  备案号:琼ICP备2022009675号-1   联系邮箱:435 227 67@qq.com