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.PortalBeanLocatorUtil;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.module.framework.service.IdentifiableOSGiService;
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 IdentifiableOSGiService) &&
076 beanName.endsWith("Service") && _log.isWarnEnabled()) {
077
078 _log.warn(
079 beanName + " should implement " +
080 IdentifiableOSGiService.class.getName() + " for " +
081 ClusterableAdvice.class.getName());
082 }
083
084 _autoInject(bean, beanName, bean.getClass());
085
086 return bean;
087 }
088
089 @Override
090 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
091 _beanFactory = beanFactory;
092 }
093
094 private void _autoInject(
095 Object targetBean, String targetBeanName, Class<?> beanClass) {
096
097 if ((beanClass == null) || beanClass.isInterface()) {
098 return;
099 }
100
101 String className = beanClass.getName();
102
103 if (className.equals(_JAVA_LANG_OBJECT) ||
104 className.startsWith(_ORG_SPRINGFRAMEWORK)) {
105
106 return;
107 }
108
109 Field[] fields = beanClass.getDeclaredFields();
110
111 for (Field field : fields) {
112 BeanReference beanReference = field.getAnnotation(
113 BeanReference.class);
114
115 String referencedBeanName = null;
116 Class<?> referencedBeanType = null;
117
118 if (beanReference != null) {
119 referencedBeanName = beanReference.name();
120 referencedBeanType = beanReference.type();
121 }
122 else {
123 continue;
124 }
125
126 if (!Object.class.equals(referencedBeanType)) {
127 referencedBeanName = referencedBeanType.getName();
128 }
129
130 Object referencedBean = _beans.get(referencedBeanName);
131
132 if (referencedBean == null) {
133 try {
134 referencedBean = _beanFactory.getBean(referencedBeanName);
135 }
136 catch (NoSuchBeanDefinitionException nsbde) {
137 try {
138 referencedBean = PortalBeanLocatorUtil.locate(
139 referencedBeanName);
140 }
141 catch (BeanLocatorException ble) {
142 StringWriter stringWriter = new StringWriter();
143
144 try (PrintWriter printWriter = new PrintWriter(
145 stringWriter)) {
146
147 printWriter.print(
148 "BeanFactory could not find bean: ");
149
150 nsbde.printStackTrace(printWriter);
151
152 printWriter.print(
153 " and PortalBeanLocator failed with: ");
154 printWriter.append(ble.getMessage());
155 }
156
157 throw new BeanLocatorException(
158 stringWriter.toString(), ble);
159 }
160 }
161
162 _beans.put(referencedBeanName, referencedBean);
163 }
164
165 ReflectionUtils.makeAccessible(field);
166
167 BeanReferenceRefreshUtil.registerRefreshPoint(
168 _beanFactory, targetBean, field, referencedBeanName);
169
170 try {
171 field.set(targetBean, referencedBean);
172 }
173 catch (Throwable t) {
174 throw new BeanCreationException(
175 targetBeanName, "Could not inject BeanReference fields", t);
176 }
177 }
178
179 _autoInject(targetBean, targetBeanName, beanClass.getSuperclass());
180 }
181
182 private static final String _JAVA_LANG_OBJECT = "java.lang.Object";
183
184 private static final String _ORG_SPRINGFRAMEWORK = "org.springframework";
185
186 private static final Log _log = LogFactoryUtil.getLog(
187 BeanReferenceAnnotationBeanPostProcessor.class);
188
189 private BeanFactory _beanFactory;
190 private final Map<String, Object> _beans = new HashMap<>();
191
192 }