KEMBAR78
比XML更好用的Java Annotation | PPT
JavaTWO  專業技術大會 Java Annotation 李日貴 (jini)
About Me jini@JWorld.TW ( jakarta99 ) SoftLeader Tech. Corp. President since 2002 Focus on dev in Java enterprise applications for Insurances, Banking and Betting. Researching and Sharing Java Opensources My Google+ ( http://gplus.to/jakarta99 ) Single now
Agenda Introduction Servlet 3.0 EJB 3.1 WebServices CDI Opensources Javassist / ASM
@Annotation Course1 Introduction
What’s annotation Begin with “@”  An Interface Set Values @Annotation @Annotation(“someValue”) @Annotation(var1=“someA”,var2=“someB”) @Annotation(value={“Apple”, “Banana”, “Cherry”})
RetentionPolicy
@Annotation Runtime Default value Stereotype Find the classes contain @Annotation Initialize them as what you want To generate the codes or xml and etc..
 
@Target(ElementType) @AnnoTarget( TYPE ) public class TheTarget { @AnnoTarget( FIELD ) private String globalMsg; @AnnoTarget( CONSTRUCTOR ) public TheTarget() { // This is a constructor } @AnnoTarget( METHOD ) public void someMethod ( @AnnoTarget ( PARAMETER )   String myParam) { // This is a method } }
@Annotation Course 2  Servlet 3.0
Servlet 2.5 package  javatwo.annotation ; public class  CatServlet  extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException  { // do something } } web.xml <web-app> <servlet> <servlet-name> CatServlet </servlet-name> <servlet-class> javatwo.annotation.CatServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name> CatServlet </servlet-name> < url-pattern >/cat</ url-pattern > </servlet-mapping> </web-app>
Servlet 3.0 package  javatwo.annotation ; @WebServlet(“/cat”) public class  CatServlet  extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // do something } } @WebServlet (name = &quot;catServlet&quot;, urlPatterns = &quot;/cat&quot;,   initParams = {  @WebInitParam (name = &quot;name&quot;, value = &quot;bobo&quot;) })
Servlet 3.0 No web.xml needed @WebServlet - Define a Servlet @WebFilter - Define a Filter @WebListener   - Define a Listener @WebInitParam - Define init parameter @MultipartConfig -  Define upload properties Can use web.xml to override values that specified by the Annotations.
FileUpload in Servlet 3.0 @WebServlet(“/upload”) @MultipartConfig(location=“c:\\tmp”) public class FileUploadServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Collection< Part > parts =  request.getParts(); for( Part part:parts) { part.write(“upload.txt”);  // save to c:\tmp\upload.txt } }
set Async in Servlet 3.0 @WebServlet(name=“AsyncServlet”, urlPatterns=“/async”,  asyncSupported=“true”) public class AsyncServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) { AsyncContext aCtx = request.startAsync(request, response);  ServletContext sc = request.getServletContext(); ((Queue<AsyncContext>)sc.getAttribute(“slowQueue&quot;)).add(aCtx); } } @WebListener public class SlowQueueListener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { … } }
@Annotation Course 3  EJB 3.1
EJB 2.x public interface CalculatorLocal extends EJBLocalObject {..} public interface CalculatorLocalHome extends EJBLocalHome {..} public class CalculatorBean implements SessionBean { .. } ejb-jar.xml <ejb-jar> <enterprise-beans> <session> <ejb-name>calculator</ejb-name> <local-home>CalculatorLocalHome</local-home> <local>CalculatorLocal</local> <ejb-class>CalculatorBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> </ejb-jar>
EJB 3.0 @Local  public interface CalculatorLocal  extends EJBLocalObject  {..} public interface CalculatorHome extends EJBHome {..} @Stateless  public class CalculatorBean implements CalculatorLocal{ .. } ejb-jar.xml
EJB 3.1 (LocalBean) @Local  public interface CalculatorLocal extends EJBLocalObject {..} public interface CalculatorHome extends EJBHome {..} @Stateless  public class CalculatorBean  implements CalculatorLocal { .. } ejb-jar.xml
Singleton SessionBean @Singleton @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) public class SingletonBean { private int clickCount = 0; @Lock(LockType.WRITE) public int getClickCount() { return clickCount++; } } //Thread-Safe, Transactional
Schedule Timer @Singleton public class TransFileBean { @Schedule(minute=“0”,hour=“4”,dayOfMonth=“Last”) public void trans() { // do transfer } }
@Annotation Course 4  WebServices
WebServices “ Big” WebServices SOAP JAX-WS javax.jws.* RESTful WebServices REST JAX-RS javax.ws.rs.*
SOAP WebService import  javax.jws. WebMethod; import  javax.jws. WebService; @WebService(serviceName=“helloService”) public class Hello { @WebMethod public String sayHello(String name) { return “Hello “+name; } }
 
RESTful WebService import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path(&quot;/helloREST/{ name }&quot;) public class HelloREST { @GET @Produces(MediaType.TEXT_PLAIN) public String getHello (@PathParam(&quot; name &quot;)  String name) { return &quot;Hello *&quot;+name+&quot;* from JAX-RS&quot;; } }
 
@Annotation Course 5  CDI
Resource Injection JEE5 @WebServlet(“/product”) public ProductServlet extends HttpServlet { @Inject private ProductBean productBean; .. } @Stateless public class ProductBean { .. }
Ambiguous Inject @Qualifier public @interface CarPolicyNo { } @Qualifier public @interface FirePolicyNo { } @CarPolicyNoGenerator public class CarPolicyNoGenerator implements PolicyNoGenerator {.. } @FirePolicyNoGenerator public class FirePolicyNoGenerator implements PolicyNoGenerator{ .. } public class FireService { @Inject @FirePolicyNoGenerator private PolicyNoGenerator policyNoGenerator; }
@Produces public class DatabaseProducer { @Produces  @PersistenceContext(unitName=“ds1”) @FireDatabase private EntityManager em; } public class FireService { @Inject   @FireDatabase private EntityManager em; }
@Annotation Course 6  Opensources
jUnit 3.x import junit.framework.Assert; import junit.framework.TestCase; public class CalculateServiceTest3  extends TestCase  { public void  setUp () throws Exception { } public void  test Sum() { int actual = new CalculateService().sum(3,5); Assert.assertEquals( 8 , actual ); } public void  tearDown () throws Exception { } }
jUnit 4.x public class CalculateServiceTest4  extends TestCase  { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Before public void beforeTest() throws Exception {  } @Test public void theSum() { Assert.assertEquals(8, new CalculateService().sum(3, 5)) ;   }  @After public void afterTest() throws Exception {  } @AfterClass public static void tearDownAfterClass() throws Exception {  } }
 
Spring 2.5 <beans> <bean id=“newsDao” class=“javatwo.annotation.spring.NewsDao”/> <bean id=“newsService” class=“javatwo.annotation.spring.NewsService”> <property name=“newsDao”> <ref bean=“newsDao”/> </property> </bean> </beans> @Service public class NewsService { @Autowired private NewsDao newsDao; }
Spring 3.0 @Named public class NewsService { @Inject private NewsDao newsDao; }
Spring 3.0 @Configuration public class AppConfig { private  @Value(“#{sysprop.dbURL}”)  String dbURL; private  @Value(“#{sysprop.username}”)  String username; private  @Value(“#{sysprop.password}”)  String password; @Bean public DataSource dataSource() { return new DriverManagerDataSource(dbURL, username, password ); } }
MVC in Spring3.0 @Controller @RequestMapping(“/news”) public class NewsController { @RequestMaaping(value=“{id}”,  method=RequestMethod.GET)   public ModelAndView getById( @PathVariable(“id”)  Long id) { return … } }
@Annotation Course 7  Javassist / ASM
Reflection Class myClass = MyClass.class; Method[] myMethods = myClass. getMethods() ; for(Method myMethod:myMethods) { Annotation[]  annotations = myMethod. getAnnotations (); for(  Annotation  annotation:annotations) { if( annotation  instanceof   MyAnno  ) { MyAnno  myAnno = ( MyAnno ) annotation; // do something } } }
Scan in ClassLoader scannotation.sf.net project ( based on javassist ) URL[] urls = ClasspathUrlFinder.findClassPaths(); AnnotationDB db = new AnnotationDB(); db. scanArchives (urls); Map<String, Set<String>> annoIndex = db.getAnnotationIndex(); Set<String> aClassNames = annoIndex.get( “javatwo.annotation.MyAnno” ); for( String aClassName:aClassNames ) { .. } // in Web, WarUrlFinder. findWebInfClassesPath ( this .getServletContext());
Get the Annotation values ClassPool pool = ClassPool.getDefault(); pool.insertClassPath(new ClassClassPath(this.getClass)); CtClass  cc = pool.get(aClassName); Object[] annos = cc.getAnnotations(); for( Object anno : annos ) { if( anno instanceof MyAnno ) { MyAnno myAnno = (MyAnno) anno; // do myAnno.var1(), myAnno.var2() } }
Class R/W in ASM public class  ScanMyDocVisitor   implements   ClassVisitor  { public  AnnotationVisistor  visitAnnotation(String desc, boolean visible) { } } // in Controller for(String className: classNames){ ScanMyDocVisitor  sv = new  ScanMyDocVisitor (); ClassReader  cr = new ClassReader(Thread.currentThread().getContextClassLoader().getResouceAsStream(className)); cr.accept(sv, 0); List<AnnotationNode> annotationList  = sv.getVisibleAnnotations(); .. }
 

比XML更好用的Java Annotation

  • 1.
    JavaTWO 專業技術大會Java Annotation 李日貴 (jini)
  • 2.
    About Me jini@JWorld.TW( jakarta99 ) SoftLeader Tech. Corp. President since 2002 Focus on dev in Java enterprise applications for Insurances, Banking and Betting. Researching and Sharing Java Opensources My Google+ ( http://gplus.to/jakarta99 ) Single now
  • 3.
    Agenda Introduction Servlet3.0 EJB 3.1 WebServices CDI Opensources Javassist / ASM
  • 4.
  • 5.
    What’s annotation Beginwith “@” An Interface Set Values @Annotation @Annotation(“someValue”) @Annotation(var1=“someA”,var2=“someB”) @Annotation(value={“Apple”, “Banana”, “Cherry”})
  • 6.
  • 7.
    @Annotation Runtime Defaultvalue Stereotype Find the classes contain @Annotation Initialize them as what you want To generate the codes or xml and etc..
  • 8.
  • 9.
    @Target(ElementType) @AnnoTarget( TYPE) public class TheTarget { @AnnoTarget( FIELD ) private String globalMsg; @AnnoTarget( CONSTRUCTOR ) public TheTarget() { // This is a constructor } @AnnoTarget( METHOD ) public void someMethod ( @AnnoTarget ( PARAMETER ) String myParam) { // This is a method } }
  • 10.
  • 11.
    Servlet 2.5 package javatwo.annotation ; public class CatServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // do something } } web.xml <web-app> <servlet> <servlet-name> CatServlet </servlet-name> <servlet-class> javatwo.annotation.CatServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name> CatServlet </servlet-name> < url-pattern >/cat</ url-pattern > </servlet-mapping> </web-app>
  • 12.
    Servlet 3.0 package javatwo.annotation ; @WebServlet(“/cat”) public class CatServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // do something } } @WebServlet (name = &quot;catServlet&quot;, urlPatterns = &quot;/cat&quot;, initParams = { @WebInitParam (name = &quot;name&quot;, value = &quot;bobo&quot;) })
  • 13.
    Servlet 3.0 Noweb.xml needed @WebServlet - Define a Servlet @WebFilter - Define a Filter @WebListener - Define a Listener @WebInitParam - Define init parameter @MultipartConfig - Define upload properties Can use web.xml to override values that specified by the Annotations.
  • 14.
    FileUpload in Servlet3.0 @WebServlet(“/upload”) @MultipartConfig(location=“c:\\tmp”) public class FileUploadServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Collection< Part > parts = request.getParts(); for( Part part:parts) { part.write(“upload.txt”); // save to c:\tmp\upload.txt } }
  • 15.
    set Async inServlet 3.0 @WebServlet(name=“AsyncServlet”, urlPatterns=“/async”, asyncSupported=“true”) public class AsyncServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) { AsyncContext aCtx = request.startAsync(request, response); ServletContext sc = request.getServletContext(); ((Queue<AsyncContext>)sc.getAttribute(“slowQueue&quot;)).add(aCtx); } } @WebListener public class SlowQueueListener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { … } }
  • 16.
  • 17.
    EJB 2.x publicinterface CalculatorLocal extends EJBLocalObject {..} public interface CalculatorLocalHome extends EJBLocalHome {..} public class CalculatorBean implements SessionBean { .. } ejb-jar.xml <ejb-jar> <enterprise-beans> <session> <ejb-name>calculator</ejb-name> <local-home>CalculatorLocalHome</local-home> <local>CalculatorLocal</local> <ejb-class>CalculatorBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> </ejb-jar>
  • 18.
    EJB 3.0 @Local public interface CalculatorLocal extends EJBLocalObject {..} public interface CalculatorHome extends EJBHome {..} @Stateless public class CalculatorBean implements CalculatorLocal{ .. } ejb-jar.xml
  • 19.
    EJB 3.1 (LocalBean)@Local public interface CalculatorLocal extends EJBLocalObject {..} public interface CalculatorHome extends EJBHome {..} @Stateless public class CalculatorBean implements CalculatorLocal { .. } ejb-jar.xml
  • 20.
    Singleton SessionBean @Singleton@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) public class SingletonBean { private int clickCount = 0; @Lock(LockType.WRITE) public int getClickCount() { return clickCount++; } } //Thread-Safe, Transactional
  • 21.
    Schedule Timer @Singletonpublic class TransFileBean { @Schedule(minute=“0”,hour=“4”,dayOfMonth=“Last”) public void trans() { // do transfer } }
  • 22.
  • 23.
    WebServices “ Big”WebServices SOAP JAX-WS javax.jws.* RESTful WebServices REST JAX-RS javax.ws.rs.*
  • 24.
    SOAP WebService import javax.jws. WebMethod; import javax.jws. WebService; @WebService(serviceName=“helloService”) public class Hello { @WebMethod public String sayHello(String name) { return “Hello “+name; } }
  • 25.
  • 26.
    RESTful WebService importjavax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path(&quot;/helloREST/{ name }&quot;) public class HelloREST { @GET @Produces(MediaType.TEXT_PLAIN) public String getHello (@PathParam(&quot; name &quot;) String name) { return &quot;Hello *&quot;+name+&quot;* from JAX-RS&quot;; } }
  • 27.
  • 28.
  • 29.
    Resource Injection JEE5@WebServlet(“/product”) public ProductServlet extends HttpServlet { @Inject private ProductBean productBean; .. } @Stateless public class ProductBean { .. }
  • 30.
    Ambiguous Inject @Qualifierpublic @interface CarPolicyNo { } @Qualifier public @interface FirePolicyNo { } @CarPolicyNoGenerator public class CarPolicyNoGenerator implements PolicyNoGenerator {.. } @FirePolicyNoGenerator public class FirePolicyNoGenerator implements PolicyNoGenerator{ .. } public class FireService { @Inject @FirePolicyNoGenerator private PolicyNoGenerator policyNoGenerator; }
  • 31.
    @Produces public classDatabaseProducer { @Produces @PersistenceContext(unitName=“ds1”) @FireDatabase private EntityManager em; } public class FireService { @Inject @FireDatabase private EntityManager em; }
  • 32.
  • 33.
    jUnit 3.x importjunit.framework.Assert; import junit.framework.TestCase; public class CalculateServiceTest3 extends TestCase { public void setUp () throws Exception { } public void test Sum() { int actual = new CalculateService().sum(3,5); Assert.assertEquals( 8 , actual ); } public void tearDown () throws Exception { } }
  • 34.
    jUnit 4.x publicclass CalculateServiceTest4 extends TestCase { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Before public void beforeTest() throws Exception { } @Test public void theSum() { Assert.assertEquals(8, new CalculateService().sum(3, 5)) ; } @After public void afterTest() throws Exception { } @AfterClass public static void tearDownAfterClass() throws Exception { } }
  • 35.
  • 36.
    Spring 2.5 <beans><bean id=“newsDao” class=“javatwo.annotation.spring.NewsDao”/> <bean id=“newsService” class=“javatwo.annotation.spring.NewsService”> <property name=“newsDao”> <ref bean=“newsDao”/> </property> </bean> </beans> @Service public class NewsService { @Autowired private NewsDao newsDao; }
  • 37.
    Spring 3.0 @Namedpublic class NewsService { @Inject private NewsDao newsDao; }
  • 38.
    Spring 3.0 @Configurationpublic class AppConfig { private @Value(“#{sysprop.dbURL}”) String dbURL; private @Value(“#{sysprop.username}”) String username; private @Value(“#{sysprop.password}”) String password; @Bean public DataSource dataSource() { return new DriverManagerDataSource(dbURL, username, password ); } }
  • 39.
    MVC in Spring3.0@Controller @RequestMapping(“/news”) public class NewsController { @RequestMaaping(value=“{id}”, method=RequestMethod.GET) public ModelAndView getById( @PathVariable(“id”) Long id) { return … } }
  • 40.
    @Annotation Course 7 Javassist / ASM
  • 41.
    Reflection Class myClass= MyClass.class; Method[] myMethods = myClass. getMethods() ; for(Method myMethod:myMethods) { Annotation[] annotations = myMethod. getAnnotations (); for( Annotation annotation:annotations) { if( annotation instanceof MyAnno ) { MyAnno myAnno = ( MyAnno ) annotation; // do something } } }
  • 42.
    Scan in ClassLoaderscannotation.sf.net project ( based on javassist ) URL[] urls = ClasspathUrlFinder.findClassPaths(); AnnotationDB db = new AnnotationDB(); db. scanArchives (urls); Map<String, Set<String>> annoIndex = db.getAnnotationIndex(); Set<String> aClassNames = annoIndex.get( “javatwo.annotation.MyAnno” ); for( String aClassName:aClassNames ) { .. } // in Web, WarUrlFinder. findWebInfClassesPath ( this .getServletContext());
  • 43.
    Get the Annotationvalues ClassPool pool = ClassPool.getDefault(); pool.insertClassPath(new ClassClassPath(this.getClass)); CtClass cc = pool.get(aClassName); Object[] annos = cc.getAnnotations(); for( Object anno : annos ) { if( anno instanceof MyAnno ) { MyAnno myAnno = (MyAnno) anno; // do myAnno.var1(), myAnno.var2() } }
  • 44.
    Class R/W inASM public class ScanMyDocVisitor implements ClassVisitor { public AnnotationVisistor visitAnnotation(String desc, boolean visible) { } } // in Controller for(String className: classNames){ ScanMyDocVisitor sv = new ScanMyDocVisitor (); ClassReader cr = new ClassReader(Thread.currentThread().getContextClassLoader().getResouceAsStream(className)); cr.accept(sv, 0); List<AnnotationNode> annotationList = sv.getVisibleAnnotations(); .. }
  • 45.