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

汽车音响网站建设/苏州seo营销

汽车音响网站建设,苏州seo营销,互联网建设,成立学校网站建设小组2020博客地址汇总2019年博客汇总 转载:https://blog.csdn.net/geekjoker/article/details/79868945 "对于Spring框架,现实公司使用的非常广泛,但是由于业务的复杂程度不同,了解到很多小伙伴们利用Spring开发仅仅是利用了Spr…
  • 2020博客地址汇总
  • 2019年博客汇总

转载:https://blog.csdn.net/geekjoker/article/details/79868945

"对于Spring框架,现实公司使用的非常广泛,但是由于业务的复杂程度不同,了解到很多小伙伴们利用Spring开发仅仅是利用了Spring的IOC,即使是AOP也很少用,但是目前的Spring是一个大家族,形成了一个很大的生态,覆盖了我们平时开发的方方面面,抛开特殊的苛刻要求之外,Spring的生态其实已经很全面了,所以在此开个系列来研究下Spring提供给我们的一些平时不太却又很实用的内容。"

说明:

对于Spring开发时,我们有时会遇到同一个接口有多个实现类,为了避免错误,我们通常在具体调用的地方通过ApplicationContext根据业务的需要来选择不同的接口实现类,虽然可以在抽象出一个工厂方法,但是还是感觉不够优雅,如果通过@Autowired直接引入接口,则需要在某个实现类上标注@Primary,否则会报错。那么书归正传如何优雅的解决上述的问题呢,此处就介绍一种利用Spring的BeanPostProcessor来处理。话不多说先上接口

示例:

1、声明接口

public interface HelloService {public void sayHello();
}

2、对应的接口实现类1:

@Service
public class HelloServiceImpl1 implements HelloService{@Overridepublic void sayHello() {System.out.println("你好我是HelloServiceImpl1");}
}

3、对应接口实现类2:

@Service
public class HelloServiceImpl2 implements HelloService{@Overridepublic void sayHello() {System.out.println("你好我是HelloServiceImpl2");}
}

4、自定义注解:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface RountingInjected {String value() default "helloServiceImpl1";
}

5、自定义BeanPostProcessor实现类:

@Component
public class HelloServiceInjectProcessor implements BeanPostProcessor {@Autowiredprivate ApplicationContext applicationContext;@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {Class<?> targetCls = bean.getClass();Field[] targetFld = targetCls.getDeclaredFields();for (Field field : targetFld) {//找到制定目标的注解类if (field.isAnnotationPresent(RountingInjected.class)) {if (!field.getType().isInterface()) {throw new BeanCreationException("RoutingInjected field must be declared as an interface:" + field.getName()+ " @Class " + targetCls.getName());}try {this.handleRoutingInjected(field, bean, field.getType());} catch (IllegalAccessException e) {e.printStackTrace();}}}return bean;}/*** @param field* @param bean* @param type* @throws IllegalAccessException*/private void handleRoutingInjected(Field field, Object bean, Class type) throws IllegalAccessException {Map<String, Object> candidates = this.applicationContext.getBeansOfType(type);field.setAccessible(true);if (candidates.size() == 1) {field.set(bean, candidates.values().iterator().next());} else if (candidates.size() == 2) {String injectVal = field.getAnnotation(RountingInjected.class).value();Object proxy = RoutingBeanProxyFactory.createProxy(injectVal, type, candidates);field.set(bean, proxy);} else {throw new IllegalArgumentException("Find more than 2 beans for type: " + type);}}

6、对应的代理实现类:

public class RoutingBeanProxyFactory {private final static String DEFAULT_BEAN_NAME = "helloServiceImpl1";public static Object createProxy(String name, Class type, Map<String, Object> candidates) {ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.setInterfaces(type);proxyFactory.addAdvice(new VersionRoutingMethodInterceptor(name, candidates));return proxyFactory.getProxy();}static class VersionRoutingMethodInterceptor implements MethodInterceptor {private Object targetObject;public VersionRoutingMethodInterceptor(String name, Map<String, Object> beans) {this.targetObject = beans.get(name);if (this.targetObject == null) {this.targetObject = beans.get(DEFAULT_BEAN_NAME);}}@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {return invocation.getMethod().invoke(this.targetObject, invocation.getArguments());}}
}

7、结果测试类

@Component
public class HelloServiceTest {@RountingInjected(value = "helloServiceImpl2")private HelloService helloService;public void testSayHello() {helloService.sayHello();}public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("colin.spring.basic.advanced.bbp");HelloServiceTest helloServiceTest = applicationContext.getBean(HelloServiceTest.class);helloServiceTest.testSayHello();}

上述是整个解决方案的示例流程,其核心思想就是根据自定义注解拦截要注入的接口实现类,运用java反射和代理的知识点来进行有效的实现类注入。

再次补充下BeanPostProcessor的一些知识点,

 

BeanPostProcessor接口作用:

     如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。

Spring中Bean的实例化过程图示:

注意:

1、接口中的两个方法都要将传入的bean返回,而不能返回null,如果返回的是null那么我们通过getBean方法将得不到目标。

 

2、BeanFactory和ApplicationContext对待bean后置处理器稍有不同。ApplicationContext会自动检测在配置文件中实现了BeanPostProcessor接口的所有bean,并把它们注册为后置处理器,然后在容器创建bean的适当时候调用它,因此部署一个后置处理器同部署其他的bean并没有什么区别。而使用BeanFactory实现的时候,bean 后置处理器必须通过代码显式地去注册,在IoC容器继承体系中的ConfigurableBeanFactory接口中定义了注册方法

 

/**  * Add a new BeanPostProcessor that will get applied to beans created  * by this factory. To be invoked during factory configuration.  * <p>Note: Post-processors submitted here will be applied in the order of  * registration; any ordering semantics expressed through implementing the  * {@link org.springframework.core.Ordered} interface will be ignored. Note  * that autodetected post-processors (e.g. as beans in an ApplicationContext)  * will always be applied after programmatically registered ones.  * @param beanPostProcessor the post-processor to register  */    
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

另外,不要将BeanPostProcessor标记为延迟初始化。因为如果这样做,Spring容器将不会注册它们,自定义逻辑也就无法得到应用。假如你在<beans />元素的定义中使用了'default-lazy-init'属性,请确信你的各个BeanPostProcessor标记为'lazy-init="false"'。

 

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor是BeanPostProcessor的子接口,可以在Bean生命周期的另外两个时期提供扩展的回调接口, 即实例化Bean之前(调用postProcessBeforeInstantiation方法)和实例化Bean之后(调用postProcessAfterInstantiation方法), 该接口定义如下:

package org.springframework.beans.factory.config;    import java.beans.PropertyDescriptor;    import org.springframework.beans.BeansException;    
import org.springframework.beans.PropertyValues;    public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {    Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;    boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;    PropertyValues postProcessPropertyValues(    PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)    throws BeansException;    }  

其使用方法与上面介绍的BeanPostProcessor接口类似,只时回调时机不同。

 

如果是使用ApplicationContext来生成并管理Bean的话则稍有不同,使用ApplicationContext来生成及管理Bean实例的话,在执行BeanFactoryAware的setBeanFactory()阶段后,若Bean类上有实现org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,接着才执行BeanPostProcessors的ProcessBeforeInitialization()及之后的流程。

 

 

 

http://www.lbrq.cn/news/1755091.html

相关文章:

  • 制作电商网站/信息流优化师发展前景
  • 一个人做b2b2c网站/网络营销的策略有哪些
  • 想做个赚钱的网站不知道做那种/seo推广seo技术培训
  • 做政务网站/网站之家
  • 广西防城港建设厅网站/百度seo发帖推广
  • 企业型网站有哪些特点/成品app直播源码有什么用
  • 网站制作网页/网站开发用什么软件
  • 做个人网站用什么程序/如何做google推广
  • 网站建设与管理好过吗/广州网站运营专注乐云seo
  • 北京东城区做网站的公司/互联网去哪里学
  • 广告设计与制作工资一般多少/百度seo收录软件
  • 龙岩网站推广公司/无锡百度正规推广
  • 微信官方网站公众平台/可以发广告的平台
  • 模板网点地址信息错误获取发货地址失败/宁德seo推广
  • 襄阳做公司网站的软件公司/友链交换网站
  • 选一个网站做seo/如何设计网站的首页
  • 南充做网站/如何进行网站性能优化?
  • 云南网站公司/一句简短走心文案
  • 做网站 绍兴/免费模板网站
  • 盘县 网站建设/网络营销策划方案800字
  • 学院网站建设方案/外贸获客软件
  • 专业网站 建设公司/百度一下 你就知道首页官网
  • 网站标ico怎么做/关键词排名查询官网
  • 网站建设怎么样/中国十大小说网站排名
  • 手机移动端网站怎么做的/软文代写平台
  • 平面设计接单赚钱吗/关键词优化需要从哪些方面开展?
  • 电商网站制作成手机app/国家认可的赚钱软件
  • 亿唐网不做网站做品牌案例分析/网站友情链接查询
  • 做平面设计在那个网站上找图好/百度seo软件
  • 网站备案 服务内容/广东深圳疫情最新
  • JavaSE -- 数组详细讲解(数组介绍,Arrays常用方法,二维数组创建)
  • 【Flutter】深入理解 Provider:不仅仅是Consumer
  • 闲庭信步使用图像验证平台加速FPGA的开发:第二十课——图像还原的FPGA实现
  • 高光谱相机有多少种类型?分别有什么特点?
  • 使用YOLOv11实现水果类别检测:从数据到模型训练的全过程
  • 7.16 Java基础 | 集合框架(上)