为了实现向struts2的Action中注入ejb3,我写了一个Annotation用来定义要注入哪个ejb3,又写了一个struts2的interceptor用来实施注入。Annotation代码如下:
@Retention(value=RetentionPolicy.RUNTIME)
@Target(value={ElementType.METHOD})
@Inherited
public @interface JndiLookup {
String jndi();
Class type();
}
@Target(value={ElementType.METHOD})
@Inherited
public @interface JndiLookup {
String jndi();
Class type();
}
Interceptor代码如下:
public class JndiLookupInterceptor implements Interceptor {
private InitialContext contaxt;
public void destroy() {
;
}
public void init() {
try {
contaxt = new InitialContext();
} catch (NamingException e) {
e.printStackTrace();
}
}
public String intercept(ActionInvocation invocation)
throws Exception {
Method[] methods = invocation.getAction()
.getClass().getMethods();
for(Method method : methods) {
try{
Class[] parameterTypes
= method.getParameterTypes();
if(parameterTypes.length != 1) {
continue;
}
JndiLookup jndiLookup
= method.getAnnotation(JndiLookup.class);
if(jndiLookup == null) {
continue;
}
if(jndiLookup.jndi() == null
|| jndiLookup.jndi().length() == 0) {
continue;
}
if(jndiLookup.type() == null) {
continue;
}
Object object = this.contaxt.lookup(jndiLookup.jndi());
method.invoke(invocation.getAction(),
new Object[] {jndiLookup.type().cast(object)});
} catch (Exception e) {
e.printStackTrace();
;
}
}
return invocation.invoke();
}
}
private InitialContext contaxt;
public void destroy() {
;
}
public void init() {
try {
contaxt = new InitialContext();
} catch (NamingException e) {
e.printStackTrace();
}
}
public String intercept(ActionInvocation invocation)
throws Exception {
Method[] methods = invocation.getAction()
.getClass().getMethods();
for(Method method : methods) {
try{
Class[] parameterTypes
= method.getParameterTypes();
if(parameterTypes.length != 1) {
continue;
}
JndiLookup jndiLookup
= method.getAnnotation(JndiLookup.class);
if(jndiLookup == null) {
continue;
}
if(jndiLookup.jndi() == null
|| jndiLookup.jndi().length() == 0) {
continue;
}
if(jndiLookup.type() == null) {
continue;
}
Object object = this.contaxt.lookup(jndiLookup.jndi());
method.invoke(invocation.getAction(),
new Object[] {jndiLookup.type().cast(object)});
} catch (Exception e) {
e.printStackTrace();
;
}
}
return invocation.invoke();
}
}
需要被注入的Action代码如下:
public class SomeAction {
private DataSource ds;
@JndiLookup(jndi="jdbc/mysqlDS", type=DataSource.class)
public void setDs(DataSource ds) {
this.ds = ds;
}
public String execute() {
//do something about the ds
}
}
private DataSource ds;
@JndiLookup(jndi="jdbc/mysqlDS", type=DataSource.class)
public void setDs(DataSource ds) {
this.ds = ds;
}
public String execute() {
//do something about the ds
}
}
经测试,在tomcat下注入DataSource成功了。看来Annotation和Struts2真的是个好东西呀!
好!
这与struts2有什么关系 理论上你这个思路可给任何servlet注射数据源(换成使用filter) 而不光光是struts2
你说的是呀,不过如果是servlet的话,就用不着费这么大的力气了,servlet里可以通过@Resource注入JNDI资源。可惜@Resource只能用于标准的那几种组件,不包括struts2的action呀。