方法一:(不推荐) 把要引用的bean定义为静态变量
代码:
public class RoleAssignmentHandler implements AssignmentHandler { private static RoleService roleService; public void setRoleService(RoleService roleService) { this.roleService = roleService; } public void assign(Assignable assignable, ExecutionContext ctx) throws Exception { // TODO Auto-generated method stub } }
spring 配置文件:
<bean id=”roleAH” class=”com.xtayfjpk.oa.handler. RoleAssignmentHandler”> <property name=”roleService” ref=”roleService”/> </bean>
注:这种方法虽然可以,但是类RoleAssignmentHandler却一直引用着roleService对象,不是很好。
方法二:(不推荐) 自己创建一个spring容器实例
BeanFactory beanFactory = new ClassPathXmlApplicationContext(“xxx.xml”);
注: 如果在web中这种方式是不好的,因为这样会有两个beanFactory,它们的管理是分开的,性能也不好,这种用在测试的时候倒是可能以。
方式三:(不推荐) 用WebApplicationContextUtils来得到servlet中的spring容器
BeanFactory beanFactory = WebApplicaitonContextUtils.getRequiredWebApplicationContext(ServletActionContext.getServletContext());
注:这种方法虽然可以,但是在业务层引用到ServletActionContext,即引用到表现层的东西,这样是不规范的,依赖太重。
方法四:(不灵活) 使用JBPM中的JbpmHandlerProxy机制
spring 配置文件:
<bean id=”roleAH” class=” com.xtayfjpk.oa.handler. RoleAssignmentHandler”> <property name=”roleService” ref=”userSerivce”/> <property name=”roleName” value=”系统管理员”/> </bean>
流程定义文件:
<task name=”审批”> <assignment class=”org.springmodules.workflow.jbpm31.JbpmHandlerProxy”> <targetBean>roleAH</targetBean> <assignment> </task>
注:这种方式虽然可以,但是不灵活,如上面jbpm流程中要配置”系统管理员”,却只能在spring配置文件中配置了,但它又是属于流程的,最好是在流程定义文件中定义。
方法五:(推荐) 实现BeanFactroyAware接口得到BeanFactory
代码:
@Component("beanFactoryHelper") public class BeanFactoryHelper implements BeanFactoryAware { private static BeanFactory beanFactory; public void setBeanFactory(BeanFactory factory) throws BeansException { beanFactory = factory; } public static BeanFactory getBeanFactory() { return beanFactory; } }
注:因为实现了BeanFactoryAware接口,所以只要类BeanFactoryHelper归spring容器管理,当创建spring容器时,就会自动调用setBeanFactory方法注入BeanFactory对象
public class RoleAssignmentHandler implements AssignmentHandler { public void assign(Assignable assignable, ExecutionContext ctx) throws Exception { BeanFactroy beanFactory = BeanFactoryHelper.getBeanFactory(); } }
方法六:(推荐) 模仿jbpm中的JbpmHandlerProxy 得到spring的BeanFactory
代码:
public class BaseAutowire { protected BeanFactory getBeanFactory() { BeanFactoryLocator factoryLocator = new JbpmFactoryLocator(); BeanFactoryReference factoryReference = factoryLocator.useBeanFactory(null); if(factoryReference==null) { throw new IllegalArgumentException("no beanFactory found under key="+null); } try { return factoryReference.getFactory(); } finally { factoryReference.release(); } } } public class RoleAssignmentHandler extends BaseAutowire implements AssignmentHandler{ private static final long serialVersionUID = -7363282072324108460L; private BeanFactory beanFactory = this.getBeanFactory(); public void assign(Assignable arg0, ExecutionContext arg1) throws Exception { } }
注:在前面集成spring和jbpm时,使用spring-modules在spring配置文件中配置过org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean这个类,这个类实现了BeanFactoryAware接口,并受spring容器管理,所以会调用它的setBeanFactory()方法,在这个方法中又调用了BeanFactoryLocator.setBeanFactory(),把BeanFactory对象注入到BeanFactoryLocator类的静态变量defaultFactory中,所以所有的BeanFactoryLocator实例都可以得到BeanFactory对象。这里使用了locator模式,这是EJB中使用的一种模式,即把获取远程对象的过程封闭起来,变量了在locator中直接查找,然后locatro里面才是帮我们到远程去查找所需要的对象。
方法七:(推荐) 利用org.springframework.beans.factory.config.AutowireCapableBeanFactory
代码:
public class BaseAutowire { //getBeanFactory返回的是spring的BeanFactory //这种类型的BeanFactroy可以向不是spring管理的对象注入spring管理对象 public BaseAutowire() { ((AutowireCapableBeanFactory)getBeanFactory()) .autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true); } protected BeanFactory getBeanFactory() { BeanFactoryLocator factoryLocator = new JbpmFactoryLocator(); BeanFactoryReference factoryReference = factoryLocator.useBeanFactory(null); if(factoryReference==null) { throw new IllegalArgumentException("no beanFactory found under key="+null); } try { return factoryReference.getFactory(); } finally { factoryReference.release(); } } } public static class RoleAssignmentHandler extends BaseAutowire implements AssignmentHandler{ private static final long serialVersionUID = -7363282072324108460L; @Resource private RoleService roleService; public void setRoleService(RoleService roleService) { this.roleService = roleService; } public void assign(Assignable arg0, ExecutionContext arg1) throws Exception { } }
注:由于RoleAssignmentHandler继承了BaseAutowire,而在BaseAutowire的构造方法中用AutowireCapableBeanFactory向RoleAssignmentHandler实例注入spring对象,所以当用上面的注解方式@resource或setter方法就能够自动把spring管理的roleService对象注入到RoleAssignmentHandler对象实例中。
AutowireCapableBeanFactory类型的spring容器类型对象可以向不是spring管理的对象注入由spring管理的对象。只需要对象有@resource或setter方法,就可以实现在实例化对象的时候自动注入。