View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.message;
18  
19  import java.io.Serializable;
20  
21  import org.apache.logging.log4j.util.PerformanceSensitive;
22  
23  /**
24   * Implementation of the {@link MessageFactory} interface that avoids allocating temporary objects where possible.
25   * Message instances are cached in a ThreadLocal and reused when a new message is requested within the same thread.
26   * @see ParameterizedMessageFactory
27   * @see ReusableSimpleMessage
28   * @see ReusableObjectMessage
29   * @see ReusableParameterizedMessage
30   * @since 2.6
31   */
32  @PerformanceSensitive("allocation")
33  public final class ReusableMessageFactory implements MessageFactory2, Serializable {
34  
35      /**
36       * Instance of ReusableMessageFactory..
37       */
38      public static final ReusableMessageFactory INSTANCE = new ReusableMessageFactory();
39  
40      private static final long serialVersionUID = -8970940216592525651L;
41      private static ThreadLocal<ReusableParameterizedMessage> threadLocalParameterized = new ThreadLocal<>();
42      private static ThreadLocal<ReusableSimpleMessage> threadLocalSimpleMessage = new ThreadLocal<>();
43      private static ThreadLocal<ReusableObjectMessage> threadLocalObjectMessage = new ThreadLocal<>();
44  
45      /**
46       * Constructs a message factory.
47       */
48      public ReusableMessageFactory() {
49          super();
50      }
51  
52      private static ReusableParameterizedMessage getParameterized() {
53          ReusableParameterizedMessage result = threadLocalParameterized.get();
54          if (result == null) {
55              result = new ReusableParameterizedMessage();
56              threadLocalParameterized.set(result);
57          }
58          return result;
59      }
60  
61      private static ReusableSimpleMessage getSimple() {
62          ReusableSimpleMessage result = threadLocalSimpleMessage.get();
63          if (result == null) {
64              result = new ReusableSimpleMessage();
65              threadLocalSimpleMessage.set(result);
66          }
67          return result;
68      }
69  
70      private static ReusableObjectMessage getObject() {
71          ReusableObjectMessage result = threadLocalObjectMessage.get();
72          if (result == null) {
73              result = new ReusableObjectMessage();
74              threadLocalObjectMessage.set(result);
75          }
76          return result;
77      }
78  
79      @Override
80      public Message newMessage(final CharSequence charSequence) {
81          ReusableSimpleMessage result = getSimple();
82          result.set(charSequence);
83          return result;
84      }
85  
86      /**
87       * Creates {@link ReusableParameterizedMessage} instances.
88       *
89       * @param message The message pattern.
90       * @param params The message parameters.
91       * @return The Message.
92       *
93       * @see MessageFactory#newMessage(String, Object...)
94       */
95      @Override
96      public Message newMessage(final String message, final Object... params) {
97          return getParameterized().set(message, params);
98      }
99  
100     @Override
101     public Message newMessage(final String message, final Object p0) {
102         return getParameterized().set(message, p0);
103     }
104 
105     @Override
106     public Message newMessage(final String message, final Object p0, final Object p1) {
107         return getParameterized().set(message, p0, p1);
108     }
109 
110     @Override
111     public Message newMessage(final String message, final Object p0, final Object p1, final Object p2) {
112         return getParameterized().set(message, p0, p1, p2);
113     }
114 
115     @Override
116     public Message newMessage(final String message, final Object p0, final Object p1, final Object p2,
117             final Object p3) {
118         return getParameterized().set(message, p0, p1, p2, p3);
119     }
120 
121     @Override
122     public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
123             final Object p4) {
124         return getParameterized().set(message, p0, p1, p2, p3, p4);
125     }
126 
127     @Override
128     public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
129             final Object p4, final Object p5) {
130         return getParameterized().set(message, p0, p1, p2, p3, p4, p5);
131     }
132 
133     @Override
134     public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
135             final Object p4, final Object p5, final Object p6) {
136         return getParameterized().set(message, p0, p1, p2, p3, p4, p5, p6);
137     }
138 
139     @Override
140     public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
141             final Object p4, final Object p5, final Object p6, final Object p7) {
142         return getParameterized().set(message, p0, p1, p2, p3, p4, p5, p6, p7);
143     }
144 
145     @Override
146     public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
147             final Object p4, final Object p5, final Object p6, final Object p7, final Object p8) {
148         return getParameterized().set(message, p0, p1, p2, p3, p4, p5, p6, p7, p8);
149     }
150 
151     @Override
152     public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
153             final Object p4, final Object p5, final Object p6, final Object p7, final Object p8, final Object p9) {
154         return getParameterized().set(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
155     }
156 
157     /**
158      * Creates {@link ReusableSimpleMessage} instances.
159      *
160      * @param message The message String.
161      * @return The Message.
162      *
163      * @see MessageFactory#newMessage(String)
164      */
165     @Override
166     public Message newMessage(final String message) {
167         ReusableSimpleMessage result = getSimple();
168         result.set(message);
169         return result;
170     }
171 
172 
173     /**
174      * Creates {@link ReusableObjectMessage} instances.
175      *
176      * @param message The message Object.
177      * @return The Message.
178      *
179      * @see MessageFactory#newMessage(Object)
180      */
181     @Override
182     public Message newMessage(final Object message) {
183         ReusableObjectMessage result = getObject();
184         result.set(message);
185         return result;
186     }
187 }