Spring是Java服务端主流的开发框架,其中的依赖注入和模块化,实现了一套灵活的组件化方案。

这个相当于Spring在框架层面帮我们做好了Bean对象的管理,而且还支持注解以及很多方法来支持非侵入式的组件化方案,使得代码耦合极低,就像没有关系的两个实现,因为Spring的粘合作用,神奇的配合一起工作,后面会从注解和方法getBean来举例。

依赖注入与注解

常用@Component@Resource来支持Bean对象的声明和引用,这样Spring会自动完成Bean对象的创建和赋值。这也优雅的做到了组件化,平时工作主要还是推荐使用注解来完成,因为更加轻量级。

除了注解之外,Spring还支持xml配置bean对象,还支持配置构造函数参数等,基于xml配置可以实现比较好的灵活性,比如有两种相同接口的Cache缓存实现,基于xml配置就可以方便的在各个缓存方案中切换,而不用修改代码。

getBean组件管理

这个方法可以从容器中顶层Bean对象中筛选满足特定名字或者特定类型的对象,比如可以用来统一对实现了某个接口的对象做自动化收集,而不用关心有哪些对象实现了这个接口。这些对象完全是独立的,扩展对象彼此也不用关心。

例1:统一处理所有实现了IEventUpdatable接口的bean

// IEventUpdatable.java
public interface IEventUpdatable {
    void update();
}

// EventTest1.java
@Component
public class EventTest1 implements IEventUpdatable {
    @MonitorPerf
    @Override
    public void update() {
        System.out.println("EventTest1 update");
    }
}

// 使用
Map<String, IEventUpdatable> asrServices = applicationContext.getBeansOfType(IEventUpdatable.class);
asrServices.values().forEach( e -> e.update() );

例2:实现bean方法的动态调用

@Resource
private ApplicationContext context;

private ApiResult<Object> doInvoke(String params) {
    ApiResult<Object> result = new ApiResult<>();
    try {
        InvokeMethod invokeMethod = JSONObject.parseObject(params, InvokeMethod.class);

        Object bean = context.getBean(invokeMethod.getBeanName());
        Method method = bean.getClass().
            getDeclaredMethod(invokeMethod.getMethodName(), invokeMethod.getParameterTypes());

        Object object = method.invoke(bean, invokeMethod.getArgs());
        result.setSuccess(true).setResult(object);
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        result.setSuccess(false).setCode(100);
    }
    return result;
}