[weld] GenericDao,Spring(2.5) VS Weld

lonvea 2010-04-19
rrsy23 写道
还是做成NO DAO吧


直接一个service里面提供持久化服务就OK


DAO还是要写的。。。这一层是数据库操作独立操作。。
wuhaixing 2010-04-19
用qualifier和InjectionPoint代替Interceptor,重构更加通用的DaoFactory。

在DaoFactory中利用InjectionPoint获取所需的Dao,这就是@Produces所提供的运行时多态:
public class DaoFactory {
	@PersistenceContext EntityManager em;
	private @Inject Logger logger;
	
	@Produces @Dao(Object.class) 
	public Object createDao(InjectionPoint injectionPoint) throws Exception {

		Class<?> returnType = injectionPoint.getAnnotated().getAnnotation(Dao.class).value();
		logger.info("create dao {}",returnType.getName());
		if (!returnType.isInterface()) {  
		             throw new UnsupportedOperationException("Only results of methods " +  
		                "which produce implementations of an interface can be replaced!");  
		}  
		GenericDao genericDao = new GenericDaoImpl(em,returnType);
		
		Object result = Proxy.newProxyInstance(  
                returnType.getClassLoader(),  
                new Class[] { returnType },  
                new DaoInvocationHandler(genericDao));  
        
		return result;

	}
}


@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})

public @interface Dao {
	 @Nonbinding Class<?> value();
}


需要Dao时,声明如下:

@Dao(WidgetDao.class) Object widgetDao;

lonvea 2010-04-22
@DAO接口中要使用◎Nobinding
wuhaixing 2010-05-06
http://www.seamframework.org/Community/HowDoIRegisterAProducerForSubtypesDynamically
这个应该能让这段代码看起来更好一点,但我还没搞明白怎么用。
wuhaixing 2010-05-31
重构了一下,利用weld extension去掉injection point中的强制类型转换,改掉当初的一个错误。

DAOFactory:

public class DaoFactory {
	@PersistenceContext EntityManager em;
	private @Inject Logger logger;
	
	@Produces @Dao
	public Object createDao(InjectionPoint injectionPoint) throws Exception {
	
		Class<?> entityType = injectionPoint.getAnnotated().getAnnotation(Dao.class).value();
		if(!(injectionPoint.getMember() instanceof Field)) {
			throw new UnsupportedOperationException("Only Field injection of an interface can be proxied!");  
		}
		Class<?> daoType = ((Field)injectionPoint.getMember()).getType();
		if(!daoType.isInterface()) {
			throw new UnsupportedOperationException("Only Field injection of an interface can be proxied!");
		}
		logger.info("create dao {}",daoType);


		GenericDao genericDao = new GenericDaoImpl(em,entityType);
		
		Object result = Proxy.newProxyInstance(  
				entityType.getClassLoader(),  
                new Class[] {daoType},  
                new DaoInvocationHandler(genericDao));  
        
		return result;

	}
}



DAOTypeOverrideExtension

public class DaoTypeOverrideExtension implements Extension {
	private final Map<Class<?>, AnnotatedType<?>> typeOverrides = new HashMap<Class<?>, AnnotatedType<?>>();

	   public <T> void processAnnotatedType(@Observes final ProcessAnnotatedType<T> event)
	   {
	      AnnotatedTypeBuilder<T> builder = AnnotatedTypeBuilder.newInstance(event.getAnnotatedType());
	      builder.readAnnotationsFromUnderlyingType();
	      boolean modifiedType = false;

	      for (AnnotatedField<?> f : event.getAnnotatedType().getFields())
	      {
	         if (f.isAnnotationPresent(Dao.class))
	         {
	            builder.overrideFieldType(f.getJavaMember(), Object.class);
	            modifiedType = true;
	         }
	      }

	      if (modifiedType)
	      {
	         AnnotatedType<T> replacement = builder.create();
	         typeOverrides.put(replacement.getJavaClass(), replacement);
	         event.setAnnotatedType(replacement);
	      }
	   }

	   public boolean hasOverriddenType(final Class<?> clazz)
	   {
	      return typeOverrides.containsKey(clazz);
	   }

	   public AnnotatedType<?> getOverriddenType(final Class<?> clazz)
	   {
	      return typeOverrides.get(clazz);
	   }
}


usage:

private @Inject @Dao(Widget.class) WidgetDao widgetDao;





Global site tag (gtag.js) - Google Analytics