6 Replies Latest reply on Feb 1, 2010 3:27 PM by alin.heyoulin.qq.com

    weld+spring

    alin.heyoulin.qq.com
      Hi all
      
      I created a simple weld spring intergration. and use it to graniteds cdi under tomcat 6.0.18. I hope someone can help me to improve it. Thanks.
      
      Spring JpaInjectionService
      
      
      package com.yofc.weldboot;
      
      import java.util.Enumeration;
      import java.util.Map;
      import java.util.Map.Entry;
      
      import javax.enterprise.inject.spi.InjectionPoint;
      import javax.persistence.EntityManager;
      import javax.persistence.EntityManagerFactory;
      import javax.persistence.PersistenceContext;
      import javax.persistence.PersistenceUnit;
      import javax.servlet.ServletContext;
      
      import org.apache.commons.logging.Log;
      import org.apache.commons.logging.LogFactory;
      import org.jboss.weld.injection.spi.JpaInjectionServices;
      import org.springframework.beans.factory.DisposableBean;
      import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean;
      import org.springframework.orm.jpa.ExtendedEntityManagerCreator;
      import org.springframework.web.context.ContextLoader;
      import org.springframework.web.context.WebApplicationContext;
      
      public class SpringJpaInjectionService extends ContextLoader implements JpaInjectionServices{
           private static final Log logger = LogFactory.getLog(SpringJpaInjectionService.class);
           public static WebApplicationContext webApplicationContext;
           private ContextLoader contextLoader;
           public static ServletContext servletContext;
           public SpringJpaInjectionService(ServletContext servletCtx) {
                servletContext=servletCtx;
                try
               {
                     if (this.contextLoader == null) {
                          this.contextLoader = this;
                     }
                     webApplicationContext=this.contextLoader.initWebApplicationContext(servletContext);
               }
               catch (Exception e)
               {
                    throw new RuntimeException("Spring startup error:"+e.getMessage());
               }
           }
      
           @Override
           public EntityManager resolvePersistenceContext(InjectionPoint injectionPoint) {
                if (!injectionPoint.getAnnotated().isAnnotationPresent(PersistenceContext.class))
                {
                     throw new IllegalArgumentException("No @PersistenceContext annotation found on injection point " + injectionPoint);
                }
                String unitname=injectionPoint.getAnnotated().getAnnotation(PersistenceContext.class).unitName();
                Map<String, AbstractEntityManagerFactoryBean> emfbeans=webApplicationContext.getBeansOfType(AbstractEntityManagerFactoryBean.class, true, true);
                for(Entry<String, AbstractEntityManagerFactoryBean> entry:emfbeans.entrySet())
                {
                     AbstractEntityManagerFactoryBean absenfBean=entry.getValue();
                     if(unitname==null || unitname.equals(""))
                          return ExtendedEntityManagerCreator.createContainerManagedEntityManager(absenfBean.getNativeEntityManagerFactory());
                     else if(absenfBean.getPersistenceUnitName()!=null && absenfBean.getPersistenceUnitName().equals(unitname))
                          return ExtendedEntityManagerCreator.createContainerManagedEntityManager(absenfBean.getNativeEntityManagerFactory());
                     
                }
                return null;
           }
      
           @Override
           public EntityManagerFactory resolvePersistenceUnit(InjectionPoint injectionPoint) {
                if (!injectionPoint.getAnnotated().isAnnotationPresent(PersistenceUnit.class))
                {
                     throw new IllegalArgumentException("No @PersistenceContext annotation found on injection point " + injectionPoint);
                }
                String unitname=injectionPoint.getAnnotated().getAnnotation(PersistenceUnit.class).unitName();
                Map<String, AbstractEntityManagerFactoryBean> emfbeans=webApplicationContext.getBeansOfType(AbstractEntityManagerFactoryBean.class, true, true);
                for(Entry<String, AbstractEntityManagerFactoryBean> entry:emfbeans.entrySet())
                {
                     AbstractEntityManagerFactoryBean absenfBean=entry.getValue();
                     if(unitname==null || unitname.equals(""))
                          return absenfBean.getNativeEntityManagerFactory();
                     else if(absenfBean.getPersistenceUnitName()!=null && absenfBean.getPersistenceUnitName().equals(unitname))
                          return absenfBean.getNativeEntityManagerFactory();
                     
                }
                return null;
           }
      
           @Override
           public void cleanup() {
                if (this.contextLoader != null) {
                     this.contextLoader.closeWebApplicationContext(servletContext);
                }
                cleanupAttributes(servletContext);
           }
           private void cleanupAttributes(ServletContext sc) {
                Enumeration<?> attrNames = sc.getAttributeNames();
                while (attrNames.hasMoreElements()) {
                     String attrName = (String) attrNames.nextElement();
                     if (attrName.startsWith("org.springframework.")) {
                          Object attrValue = sc.getAttribute(attrName);
                          if (attrValue instanceof DisposableBean) {
                               try {
                                    ((DisposableBean) attrValue).destroy();
                               }
                               catch (Throwable ex) {
                                    logger.error("Couldn't invoke destroy method of attribute with name '" + attrName + "'", ex);
                               }
                          }
                     }
                }
           }
      }
      
      
      

        • 1. Re: weld+spring
          alin.heyoulin.qq.com
          Spring injectExtension
          
          
          
          package com.yofc.jcdi.extensions;
          
          import java.lang.annotation.Annotation;
          import java.util.HashSet;
          import java.util.Set;
          
          import javax.enterprise.context.spi.CreationalContext;
          import javax.enterprise.event.Observes;
          import javax.enterprise.inject.spi.AnnotatedField;
          import javax.enterprise.inject.spi.AnnotatedMethod;
          import javax.enterprise.inject.spi.AnnotatedType;
          import javax.enterprise.inject.spi.BeanManager;
          import javax.enterprise.inject.spi.Extension;
          import javax.enterprise.inject.spi.InjectionPoint;
          import javax.enterprise.inject.spi.InjectionTarget;
          import javax.enterprise.inject.spi.ProcessInjectionTarget;
          
          
          import org.apache.commons.logging.Log;
          import org.apache.commons.logging.LogFactory;
          
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
          import org.springframework.beans.factory.annotation.Value;
          import org.springframework.util.ClassUtils;
          import org.springframework.web.context.ContextLoader;
          import org.springframework.web.context.WebApplicationContext;
          
          public class SpringInjectExtension implements Extension {
               protected final Log logger = LogFactory.getLog(SpringInjectExtension.class);
               <T> void processServlet(@Observes ProcessInjectionTarget<T> pit,BeanManager bm) 
               {
                    AnnotatedType<T> annotatedType =pit.getAnnotatedType();
                    boolean hasann=false;
                    for (AnnotatedField<? super T> type : annotatedType.getFields()) {
                         if (type.isAnnotationPresent(Value.class) || type.isAnnotationPresent(Autowired.class)) {
                              hasann=true;
                         }
                    }
                    if(!hasann)
                    for (AnnotatedMethod<? super T> type : annotatedType.getMethods()) {
                         if (type.isAnnotationPresent(Value.class) || type.isAnnotationPresent(Autowired.class)) {
                              hasann=true;
                         }
                    }
                    if(!hasann)
                         return;
                    final InjectionTarget<T> it = pit.getInjectionTarget();
                    
                    InjectionTarget<T> wrapped = new InjectionTarget<T>() {
                              @Override
                              public void postConstruct(T arg0) {
                                   it.postConstruct(arg0);
                                   WebApplicationContext cc = ContextLoader.getCurrentWebApplicationContext();
                                   if (cc != null) {
                                        AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
                                        Set<Class<? extends Annotation>> anns=new HashSet<Class<? extends Annotation>>();
                                        anns.add(Value.class);
                                        anns.add(Autowired.class);
                                        bpp.setAutowiredAnnotationTypes(anns);
                                        bpp.setBeanFactory(cc.getAutowireCapableBeanFactory());
                                        bpp.processInjection(arg0);
                                   }
                                   else {
                                        if (logger.isDebugEnabled()) {
                                             logger.debug("Current WebApplicationContext is not available for processing of " +
                                                       ClassUtils.getShortName(arg0.getClass()) + ": " +
                                                       "Make sure this class gets constructed in a Spring web application. Proceeding without injection.");
                                        }
                                   }
                                   
                              }
                              @Override
                              public void preDestroy(T arg0) {
                                   it.preDestroy(arg0);
                                   
                              }
                              @Override
                              public void dispose(T arg0) {
                                   it.dispose(arg0);
                                   
                              }
                              @Override
                              public Set<InjectionPoint> getInjectionPoints() {
                                   return it.getInjectionPoints();
                              }
                              @Override
                              public T produce(CreationalContext<T> arg0) {
                                   return it.produce(arg0);
                              }
                              @Override
                              public void inject(T arg0, CreationalContext<T> arg1) {
                                   it.inject(arg0, arg1);
                                   
                              }
                       };
                       pit.setInjectionTarget(wrapped);
                 }
               }
          
          
          


          • 2. Re: weld+spring
            alin.heyoulin.qq.com
            Spring TransactionExtension
            
            package com.yofc.jcdi.annotations;
            
            import static java.lang.annotation.ElementType.METHOD;
            import static java.lang.annotation.ElementType.TYPE;
            import static java.lang.annotation.RetentionPolicy.RUNTIME;
            
            import java.lang.annotation.Documented;
            import java.lang.annotation.Retention;
            import java.lang.annotation.Target;
            
            import javax.interceptor.InterceptorBinding;
            
            @Retention(RUNTIME)
            @Target({METHOD, TYPE})
            @Documented
            @InterceptorBinding
            public @interface SpringTransactional {
            }
            
            
            
            package com.yofc.jcdi.extensions;
            
            import java.io.IOException;
            
            import javax.enterprise.event.Observes;
            import javax.enterprise.inject.spi.AnnotatedMethod;
            import javax.enterprise.inject.spi.AnnotatedType;
            import javax.enterprise.inject.spi.BeanManager;
            import javax.enterprise.inject.spi.Extension;
            import javax.enterprise.inject.spi.ProcessAnnotatedType;
            import javax.enterprise.util.AnnotationLiteral;
            
            import org.jboss.weld.extensions.util.reannotated.ReannotatedMethod;
            import org.jboss.weld.extensions.util.reannotated.ReannotatedType;
            import org.springframework.context.annotation.Bean;
            import org.springframework.context.annotation.Configuration;
            import org.springframework.stereotype.Component;
            import org.springframework.stereotype.Controller;
            import org.springframework.stereotype.Repository;
            import org.springframework.stereotype.Service;
            
            import com.yofc.jcdi.annotations.SpringTransactional;
            
            public class SpringTransactionExtension implements Extension {
                     @SuppressWarnings("serial")
                     <X> void processAnnotatedType(@Observes final ProcessAnnotatedType<X> pat, BeanManager bm) throws IOException {
                            AnnotatedType<X> annotatedType = pat.getAnnotatedType();
                            if(annotatedType.isAnnotationPresent(Component.class) 
                                            || annotatedType.isAnnotationPresent(Bean.class)
                                            || annotatedType.isAnnotationPresent(Service.class)
                                            || annotatedType.isAnnotationPresent(Repository.class)
                                            || annotatedType.isAnnotationPresent(Configuration.class)
                                            || annotatedType.isAnnotationPresent(Controller.class))
                            {
                                    pat.veto();
                                    return;
                            }
                            ReannotatedType<X> rt = new ReannotatedType<X>(annotatedType);
                            if(annotatedType.isAnnotationPresent(org.springframework.transaction.annotation.Transactional.class))
                                    rt.define(new AnnotationLiteral<SpringTransactional>(){});
                            for (AnnotatedMethod<? super X> type : rt.getMethods()) {
                                    if (type.isAnnotationPresent(org.springframework.transaction.annotation.Transactional.class) ) {
                                            ReannotatedMethod<? super X> rm=rt.getMethod(type.getJavaMember());
                                            rm.define(new AnnotationLiteral<SpringTransactional>(){});
                                    }
                            }                       
                            pat.setAnnotatedType(rt);
                    }
            }
            
            
            
            package com.yofc.jcdi.interceptors;
            
            import java.io.Serializable;
            import java.lang.reflect.InvocationTargetException;
            
            import javax.interceptor.AroundInvoke;
            import javax.interceptor.Interceptor;
            import javax.interceptor.InvocationContext;
            
            
            import org.apache.log4j.Logger;
            import org.springframework.aop.framework.ProxyFactory;
            import org.springframework.transaction.interceptor.TransactionInterceptor;
            import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
            
            import com.yofc.jcdi.annotations.SpringTransactional;
            import com.yofc.weldboot.SpringJpaInjectionService;
            @Interceptor
            @SpringTransactional 
            public class SpringTransactionInterceptor implements Serializable{
               
               /**
                     * 
                     */
                    private static final long serialVersionUID = 1L;
               // private @Inject HttpSession session;
                private static final Logger log = Logger.getLogger(SpringTransactionInterceptor.class);
                @AroundInvoke
                public Object aroundInvoke(InvocationContext context) throws Throwable {
                    if(!context.getTarget().getClass().isAnnotationPresent(org.springframework.transaction.annotation.Transactional.class)
                                    && !context.getMethod().isAnnotationPresent(org.springframework.transaction.annotation.Transactional.class))
                            return context.proceed();
                        ProxyFactory proxyFactory = new ProxyFactory();
                            proxyFactory.setTarget(context.getTarget());
                            TransactionInterceptor transactionInterceptor=new TransactionInterceptor(null, new AnnotationTransactionAttributeSource());
                            transactionInterceptor.setBeanFactory(SpringJpaInjectionService.webApplicationContext);
                            proxyFactory.addAdvice(transactionInterceptor);         
                    
                   try
                   {
                    
                     return context.getMethod().invoke(proxyFactory.getProxy(),context.getParameters());              
                       
                   }catch(InvocationTargetException e)
                   {            
                       log.error("transaction error"+e.getTargetException().getMessage());
                       throw e.getTargetException();
                       
                   }
                }
            }
            
            

            • 3. Re: weld+spring
              alin.heyoulin.qq.com

              
              Spring jsr250 securityExtension
              
              
              package com.yofc.jcdi.annotations;
              
              import static java.lang.annotation.ElementType.METHOD;
              import static java.lang.annotation.ElementType.TYPE;
              import static java.lang.annotation.RetentionPolicy.RUNTIME;
              
              import java.lang.annotation.Documented;
              import java.lang.annotation.Retention;
              import java.lang.annotation.Target;
              
              import javax.interceptor.InterceptorBinding;
              
              @Retention(RUNTIME)
              @Target({METHOD, TYPE})
              @Documented
              @InterceptorBinding
              public @interface Spring250Security {
              
              }
              
              
              
              package com.yofc.jcdi.extensions;
              
              import java.io.IOException;
              
              import javax.enterprise.event.Observes;
              import javax.enterprise.inject.spi.AnnotatedMethod;
              import javax.enterprise.inject.spi.AnnotatedType;
              import javax.enterprise.inject.spi.BeanManager;
              import javax.enterprise.inject.spi.Extension;
              import javax.enterprise.inject.spi.ProcessAnnotatedType;
              import javax.enterprise.util.AnnotationLiteral;
              
              import org.jboss.weld.extensions.util.reannotated.ReannotatedMethod;
              import org.jboss.weld.extensions.util.reannotated.ReannotatedType;
              import com.yofc.jcdi.annotations.Spring250Security;
              
              public class Spring250SecurityExtension implements Extension {
                    @SuppressWarnings("serial")
                    <X> void processAnnotatedType(@Observes final ProcessAnnotatedType<X> pat, BeanManager bm) throws IOException {
                        AnnotatedType<X> annotatedType = pat.getAnnotatedType();
                        ReannotatedType<X> rt = new ReannotatedType<X>(annotatedType);
                        if(annotatedType.isAnnotationPresent(javax.annotation.security.RolesAllowed.class)
                                  || annotatedType.isAnnotationPresent(javax.annotation.security.DeclareRoles.class)
                                  || annotatedType.isAnnotationPresent(javax.annotation.security.DenyAll.class)
                                  || annotatedType.isAnnotationPresent(javax.annotation.security.PermitAll.class)
                                  || annotatedType.isAnnotationPresent(javax.annotation.security.RunAs.class))
                             rt.define(new AnnotationLiteral<Spring250Security>(){});
                        for (AnnotatedMethod<? super X> type : rt.getMethods()) {
                             if(type.isAnnotationPresent(javax.annotation.security.RolesAllowed.class)
                                       || type.isAnnotationPresent(javax.annotation.security.DeclareRoles.class)
                                       || type.isAnnotationPresent(javax.annotation.security.DenyAll.class)
                                       || type.isAnnotationPresent(javax.annotation.security.PermitAll.class)
                                       || type.isAnnotationPresent(javax.annotation.security.RunAs.class)){
                                  ReannotatedMethod<? super X> rm=rt.getMethod(type.getJavaMember());
                                  rm.define(new AnnotationLiteral<Spring250Security>(){});
                             }
                        }               
                        pat.setAnnotatedType(rt);
                   }
              }
              
              
              
              package com.yofc.jcdi.interceptors;
              
              import java.lang.reflect.InvocationTargetException;
              import java.lang.reflect.Method;
              import java.util.ArrayList;
              import java.util.List;
              
              import javax.interceptor.AroundInvoke;
              import javax.interceptor.Interceptor;
              import javax.interceptor.InvocationContext;
              
              import org.apache.log4j.Logger;
              import org.springframework.aop.framework.ProxyFactory;
              import org.springframework.beans.factory.annotation.Autowired;
              import org.springframework.security.access.AccessDecisionVoter;
              
              import org.springframework.security.access.annotation.Jsr250MethodSecurityMetadataSource;
              import org.springframework.security.access.annotation.Jsr250Voter;
              import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
              
              import org.springframework.security.access.vote.AffirmativeBased;
              import org.springframework.security.authentication.AuthenticationManager;
              
              import com.yofc.jcdi.annotations.Spring250Security;
              
              @Interceptor
              @Spring250Security
              public class Spring250SecurityInterptor {
                      
                      /**
                         * 
                         */
                        @Autowired
                        private AuthenticationManager authenticationManager;
                        private static final long serialVersionUID = 1L;
                      // private @Inject HttpSession session;
                       private static final Logger log = Logger.getLogger(Spring250SecurityInterptor.class);
                       @SuppressWarnings("unchecked")
                        @AroundInvoke
                       public Object aroundInvoke(InvocationContext context) throws Throwable {
                            Class type=context.getTarget().getClass();
                            Method method=context.getMethod();
                            if(!(type.isAnnotationPresent(javax.annotation.security.RolesAllowed.class)
                                       || type.isAnnotationPresent(javax.annotation.security.DeclareRoles.class)
                                       || type.isAnnotationPresent(javax.annotation.security.DenyAll.class)
                                       || type.isAnnotationPresent(javax.annotation.security.PermitAll.class)
                                       || type.isAnnotationPresent(javax.annotation.security.RunAs.class)) &&
                                !(method.isAnnotationPresent(javax.annotation.security.RolesAllowed.class)
                                       || method.isAnnotationPresent(javax.annotation.security.DeclareRoles.class)
                                       || method.isAnnotationPresent(javax.annotation.security.DenyAll.class)
                                       || method.isAnnotationPresent(javax.annotation.security.PermitAll.class)
                                       || method.isAnnotationPresent(javax.annotation.security.RunAs.class)))              
                                 return context.proceed();
                            ProxyFactory proxyFactory = new ProxyFactory();
                                proxyFactory.setTarget(context.getTarget());
                                MethodSecurityInterceptor methodSecurityInterceptor=new MethodSecurityInterceptor();
                                methodSecurityInterceptor.setSecurityMetadataSource(new Jsr250MethodSecurityMetadataSource());
                                methodSecurityInterceptor.setAuthenticationManager(authenticationManager);
                                AffirmativeBased affirmativeBased=new AffirmativeBased();
                                List<AccessDecisionVoter> list=new ArrayList<AccessDecisionVoter >();
                                list.add(new Jsr250Voter());
                                affirmativeBased.setDecisionVoters(list);
                                methodSecurityInterceptor.setAccessDecisionManager(affirmativeBased);
                                proxyFactory.addAdvice(methodSecurityInterceptor);       
                           
                          try
                          {
                               
                            return context.getMethod().invoke(proxyFactory.getProxy(),context.getParameters());              
                              
                          }catch(InvocationTargetException e)
                          {            
                               log.error("Security error:"+e.getTargetException().getMessage());
                              throw e.getTargetException();
                              
                          }
                       }
                   }
              
              
              


              • 4. Re: weld+spring
                alin.heyoulin.qq.com
                
                That's all
                
                Usage:
                
                
                package test.granite.cdi.service;
                
                import javax.annotation.security.RolesAllowed;
                import javax.enterprise.event.Event;
                import javax.enterprise.inject.Any;
                import javax.inject.Inject;
                import javax.persistence.EntityManager;
                import javax.persistence.PersistenceContext;
                
                import org.springframework.beans.factory.annotation.Autowired;
                import org.springframework.beans.factory.annotation.Qualifier;
                import org.springframework.jdbc.core.JdbcTemplate;
                import org.springframework.transaction.annotation.Transactional;
                
                import test.granite.cdi.entity.Person;
                import test.granite.cdi.event.RefreshEvent;
                
                public class PersonServiceBean implements PersonService {
                
                        @PersistenceContext
                        EntityManager entityManager;
                        
                        @Inject @Any
                        Event<RefreshEvent> refreshEvent;
                        
                        @Autowired
                        @Qualifier("jmsTmplate")
                        private JdbcTemplate myjmsTmplate;
                        
                        @RolesAllowed({ "admin" })
                        @Transactional
                    public Person createPerson(Person person) {
                                entityManager.persist(person);
                                refreshEvent.fire(new RefreshEvent());
                                
                        return person;
                    }
                        @Transactional
                    public Person modifyPerson(Person person) {
                                myjmsTmplate.execute("update person set firstName='heyoulin'");
                                return (Person)entityManager.merge(person);
                    }
                        @Transactional
                    public void deletePerson(Integer personId) {
                        Person person = (Person)entityManager.find(Person.class, personId);
                        entityManager.remove(person);
                                
                                refreshEvent.fire(new RefreshEvent());
                    }
                }
                


                • 5. Re: weld+spring
                  alin.heyoulin.qq.com
                  
                  Nevermind create yourself servlet Lister. Just add 
                  
                  try
                        {
                             deployment.getWebAppBeanDeploymentArchive().getServices().add(
                                       JpaInjectionServices.class, new SpringJpaInjectionService(sce.getServletContext()));
                        }
                        catch (NoClassDefFoundError e)
                        {
                            log.warn("spring injection not available in simple beans");
                        } 
                  
                  
                  to org.jboss.weld.environment.servlet.Listener.java
                  
                  
                  Hope this can help somebody to use weld easy.
                  
                  


                  • 6. Re: weld+spring
                    alin.heyoulin.qq.com

                    This code use weld extensions module. Don't forget add weld extensions module.