如果在spring bean配置中厌烦使用的大量xml,又不能对代码标以注解(annotation),可以使用beangle提供的scala方式进行bean注册。 优点是
就权限系统中常见的用户、角色、权限等服务,配置简单例子如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
package org.beangle.sample
import org.beangle.commons.inject.bind.AbstractBindModule
class DefaultModule extends AbstractBindModule {
protected override def doBinding() {
//以单例形式绑定单个bean,不必声明绑定实现类对应的接口
bind(classOf[PermissionServiceImpl])
//以单例形式绑定批量绑定多个bean
bind(classOf[UserServiceImpl],classOf[RoleServiceImpl])
//绑定Action每次使用创建新的实例
bind(classOf[UserAction]).in(Scope.PROTOTYPE)
}
}
然后,将beangle自带的SpringConfigProcessor处理器以及刚才定义的DefaultModule,注入到spring bean中,即实现bean配置。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="BeangeSpringConfigProcessor" class="org.beangle.inject.spring.config.SpringConfigProcessor">
<property name="reconfigResources" value=";classpath*:spring-config.xml"/>
</bean>
<bean class="org.beangle.sample.DefaultModule"/>
</beans>
以上的例子完成了四个bean的定义,等价与一下xml配置。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.beangle.sample.service.PermissionServiceImpl"
id="org.beangle.sample.service.PermissionServiceImpl" autowire="no"/>
<bean class="org.beangle.sample.service.UserServiceImpl"
id="org.beangle.sample.service.UserServiceImpl" autowire="no"/>
<bean class="org.beangle.sample.service.RoleServiceImpl"
id="org.beangle.sample.service.RoleServiceImpl" autowire="no"/>
<bean class="org.beangle.sample.web.action.UserAction"
id="org.beangle.sample.web.action.UserAction" autowire="no">
<property name="userService" ref="org.beangle.sample.service.UserServiceImpl"/>
<property name="roleService" ref="org.beangle.sample.service.RoleServiceImpl"/>
<property name="permissionService" ref="org.beangle.sample.service.PermissionServiceImpl"/>
</bean>
</beans>
SpringConfigProcessor后处理器,通过查询spring中注册的类似DefaultModule之类的bean,提取其中的”配置”,然后注册到spring中。 从功效上类似xml注册,在运行期间,不参与bean实例化,因此不存在运行开销。
至于bean之间的依赖关系(通过setXXX形式声明的),绑定后续处理中自行完成,无需声明类似autoWireByName,autoWireByType等自动注入策略。针对bean的某个依赖属性,实现一下注入逻辑:
上例中UserAction中使用UserService接口,自动注入逻辑中发现了符合要求的实例仅存在UserServiceImpl一个实现,直接进行注入。
目前支持spring的配置语法如下
针对list,set,map,array之类的集合属性配置
例如ProviderManager中管理了providers列表,类型为List
bind(ProviderManage.class).property("providers",list(AProvider.class,BProvider.class));
如果采用注册好的bean,采用形式如下:
bind("aprovider",AProvider.class).property("superman","admin");
bind(ProviderManage.class).property("providers",list(ref("aprovider"),BProvider.class));
而BProvider则被注册为一个名称较长的内部单例bean。或者
bind(AProvider.class).property("superman","admin");
bind(BProvider.class).property("sompeproperty","value");
bind(ProviderManage.class).property("providers",listref(AProvider.class,BProvider.class));
类似array,set,之类的可以采用set(),array()语法注入多个bean。
针对Map,采用的语法稍有不同:
bind("restrictionService", RestrictionServiceImpl.class).property("providers",
map(entry("csv", CsvDataResolver.class), entry("oql", OqlDataProvider.class))).property(
"dataResolver",IdentifierDataResolver.class);
采用entry(key,value)函数表示一个元素。
所有在集合、map中使用的Class类型数据,如果没有采用ref(Some.class)形式,而是直接使用Some.class,效果是不一样的。例如
// bind(AProvider.class,BProvider.class);不需要这样的代码了
// list(Class<?> ... classes)会直接创建bean的定义
bind(ProviderManage.class).property("providers",list(AProvider.class,BProvider.class));
//如果想使用已有的配置,则需要采用ref
bind(ProviderManage.class).property("providers",list(ref(AProvider.class),ref(BProvider.class)));
//或者使用listref
bind(ProviderManage.class).property("providers",listref(AProvider.class,BProvider.class));