View Javadoc

1   /*
2    * Copyright 2007-2012 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springbyexample.util.log;
18  
19  import java.lang.annotation.Annotation;
20  import java.lang.reflect.Field;
21  import java.lang.reflect.Method;
22  import java.lang.reflect.Modifier;
23  
24  import org.springframework.util.Assert;
25  import org.springframework.util.ReflectionUtils;
26  
27  /**
28   * <p>Injects loggers into new bean instances based on   
29   * fields marked with {@link AutowiredLogger} annotation.</p>
30   * 
31   * @author David Winterfeldt
32   */
33  public class AnnotationLoggerBeanPostProcessor extends LoggerBeanPostProcessor {
34  
35      private Class<? extends Annotation> autowiredAnnotationType = AutowiredLogger.class;
36      
37      /**
38       * Gets autowired logger annotation type.
39       * Defaults to <code>AutowiredLogger</code>.
40       */
41      protected Class<? extends Annotation> getAutowiredAnnotationType() {
42          return this.autowiredAnnotationType;
43      }
44  
45      /**
46       * Sets autowired logger annotation type.
47       * Defaults to <code>AutowiredLogger</code>.
48       */
49      public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
50          Assert.notNull(autowiredAnnotationType, "Autowired logger annotation type must not be null.");
51          this.autowiredAnnotationType = autowiredAnnotationType;
52      }
53  
54      /**
55       * <p>Processes a beans fields for injection if it has a {@link AutowiredLogger} annotation.</p>
56       * 
57       * <p><strong>Note</strong>: Method name isn't used by this implementation.</p>
58       */
59      protected void processLogger(final Object bean, final String methodName) {
60          // FIX ME: cache a classes inject data?
61          
62          final Class<?> clazz = bean.getClass();
63  
64          ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
65              public void doWith(Field field) {
66                  Annotation annotation = field.getAnnotation(getAutowiredAnnotationType());
67                  
68                  if (annotation != null) {
69                      if (Modifier.isStatic(field.getModifiers())) {
70                          throw new IllegalStateException("Autowired annotation is not supported on static fields");
71                      }
72                      
73                      ReflectionUtils.makeAccessible(field);
74                      
75                      Object logger = getLogger(bean.getClass().getName(),
76                                                field.getType().getName());
77                      
78                      ReflectionUtils.setField(field, bean, logger);
79                  }
80              }
81          });
82          
83          ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
84              public void doWith(Method method) {
85                  Annotation annotation = method.getAnnotation(getAutowiredAnnotationType());
86                  
87                  if (annotation != null) {
88                      if (Modifier.isStatic(method.getModifiers())) {
89                          throw new IllegalStateException("Autowired logger annotation is not supported on static methods");
90                      }
91                      
92                      if (method.getParameterTypes().length == 0) {
93                          throw new IllegalStateException("Autowired logger annotation requires at least one argument: " + method);
94                      }
95                      
96                      injectMethod(bean, method);
97                  }
98              }
99          });
100     }
101 
102 }