001
014
015 package com.liferay.portal.spring.bean;
016
017 import com.liferay.portal.cluster.ClusterableAdvice;
018 import com.liferay.portal.kernel.bean.BeanLocatorException;
019 import com.liferay.portal.kernel.bean.BeanReference;
020 import com.liferay.portal.kernel.bean.IdentifiableBean;
021 import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024
025 import java.io.PrintWriter;
026 import java.io.StringWriter;
027
028 import java.lang.reflect.Field;
029
030 import java.util.HashMap;
031 import java.util.Map;
032
033 import org.springframework.beans.BeansException;
034 import org.springframework.beans.factory.BeanCreationException;
035 import org.springframework.beans.factory.BeanFactory;
036 import org.springframework.beans.factory.BeanFactoryAware;
037 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
038 import org.springframework.beans.factory.config.BeanPostProcessor;
039 import org.springframework.util.ReflectionUtils;
040
041
045 public class BeanReferenceAnnotationBeanPostProcessor
046 implements BeanFactoryAware, BeanPostProcessor {
047
048 public BeanReferenceAnnotationBeanPostProcessor() {
049 if (_log.isDebugEnabled()) {
050 _log.debug("Creating instance " + this.hashCode());
051 }
052 }
053
054 public BeanReferenceAnnotationBeanPostProcessor(BeanFactory beanFactory) {
055 this();
056
057 _beanFactory = beanFactory;
058 }
059
060 public void destroy() {
061 _beans.clear();
062 }
063
064 @Override
065 public Object postProcessAfterInitialization(Object bean, String beanName)
066 throws BeansException {
067
068 return bean;
069 }
070
071 @Override
072 public Object postProcessBeforeInitialization(Object bean, String beanName)
073 throws BeansException {
074
075 if (bean instanceof IdentifiableBean) {
076 IdentifiableBean identifiableBean = (IdentifiableBean)bean;
077
078 identifiableBean.setBeanIdentifier(beanName);
079 }
080 else if (beanName.endsWith("Service")) {
081 if (_log.isWarnEnabled()) {
082 _log.warn(
083 beanName + " should implement " +
084 IdentifiableBean.class.getName() +
085 " for " + ClusterableAdvice.class.getName());
086 }
087 }
088
089 _autoInject(bean, beanName, bean.getClass());
090
091 return bean;
092 }
093
094 @Override
095 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
096 _beanFactory = beanFactory;
097 }
098
099 private void _autoInject(
100 Object targetBean, String targetBeanName, Class<?> beanClass) {
101
102 if ((beanClass == null) || beanClass.isInterface()) {
103 return;
104 }
105
106 String className = beanClass.getName();
107
108 if (className.equals(_JAVA_LANG_OBJECT) ||
109 className.startsWith(_ORG_SPRINGFRAMEWORK)) {
110
111 return;
112 }
113
114 Field[] fields = beanClass.getDeclaredFields();
115
116 for (Field field : fields) {
117 BeanReference beanReference = field.getAnnotation(
118 BeanReference.class);
119
120 String referencedBeanName = null;
121 Class<?> referencedBeanType = null;
122
123 if (beanReference != null) {
124 referencedBeanName = beanReference.name();
125 referencedBeanType = beanReference.type();
126 }
127 else {
128 continue;
129 }
130
131 if (!Object.class.equals(referencedBeanType)) {
132 referencedBeanName = referencedBeanType.getName();
133 }
134
135 Object referencedBean = _beans.get(referencedBeanName);
136
137 if (referencedBean == null) {
138 try {
139 referencedBean = _beanFactory.getBean(referencedBeanName);
140 }
141 catch (NoSuchBeanDefinitionException nsbde) {
142 try {
143 referencedBean = PortalBeanLocatorUtil.locate(
144 referencedBeanName);
145 }
146 catch (BeanLocatorException ble) {
147 StringWriter stringWriter = new StringWriter();
148
149 try (PrintWriter printWriter = new PrintWriter(
150 stringWriter)) {
151
152 printWriter.print(
153 "BeanFactory could not find bean: ");
154
155 nsbde.printStackTrace(printWriter);
156
157 printWriter.print(
158 " and PortalBeanLocator failed with: ");
159 printWriter.append(ble.getMessage());
160 }
161
162 throw new BeanLocatorException(
163 stringWriter.toString(), ble);
164 }
165 }
166
167 _beans.put(referencedBeanName, referencedBean);
168 }
169
170 ReflectionUtils.makeAccessible(field);
171
172 BeanReferenceRefreshUtil.registerRefreshPoint(
173 _beanFactory, targetBean, field, referencedBeanName);
174
175 try {
176 field.set(targetBean, referencedBean);
177 }
178 catch (Throwable t) {
179 throw new BeanCreationException(
180 targetBeanName, "Could not inject BeanReference fields", t);
181 }
182 }
183
184 _autoInject(targetBean, targetBeanName, beanClass.getSuperclass());
185 }
186
187 private static final String _JAVA_LANG_OBJECT = "java.lang.Object";
188
189 private static final String _ORG_SPRINGFRAMEWORK = "org.springframework";
190
191 private static final Log _log = LogFactoryUtil.getLog(
192 BeanReferenceAnnotationBeanPostProcessor.class);
193
194 private BeanFactory _beanFactory;
195 private final Map<String, Object> _beans = new HashMap<>();
196
197 }