@@ -99,7 +99,7 @@ public class InstanceSupplierCodeGenerator {
9999
100100
101101 /**
102- * Create a new instance.
102+ * Create a new generator instance.
103103 * @param generationContext the generation context
104104 * @param className the class name of the bean to instantiate
105105 * @param generatedMethods the generated methods
@@ -158,105 +158,108 @@ private void registerRuntimeHintsIfNecessary(RegisteredBean registeredBean, Exec
158158 private CodeBlock generateCodeForConstructor (RegisteredBean registeredBean , Constructor <?> constructor ) {
159159 String beanName = registeredBean .getBeanName ();
160160 Class <?> beanClass = registeredBean .getBeanClass ();
161- Class <?> declaringClass = constructor .getDeclaringClass ();
162161
163- Visibility accessVisibility = getAccessVisibility (registeredBean , constructor );
164162 if (KotlinDetector .isKotlinReflectPresent () && KotlinDelegate .hasConstructorWithOptionalParameter (beanClass )) {
165- return generateCodeForInaccessibleConstructor (beanName , beanClass , constructor ,
163+ return generateCodeForInaccessibleConstructor (beanName , constructor ,
166164 hints -> hints .registerType (beanClass , MemberCategory .INVOKE_DECLARED_CONSTRUCTORS ));
167165 }
168- else if (accessVisibility != Visibility .PRIVATE ) {
169- return generateCodeForAccessibleConstructor (beanName , beanClass , constructor , declaringClass );
166+
167+ if (!isVisible (constructor , constructor .getDeclaringClass ())) {
168+ return generateCodeForInaccessibleConstructor (beanName , constructor ,
169+ hints -> hints .registerConstructor (constructor , ExecutableMode .INVOKE ));
170170 }
171- return generateCodeForInaccessibleConstructor (beanName , beanClass , constructor ,
172- hints -> hints .registerConstructor (constructor , ExecutableMode .INVOKE ));
171+ return generateCodeForAccessibleConstructor (beanName , constructor );
173172 }
174173
175- private CodeBlock generateCodeForAccessibleConstructor (String beanName , Class <?> beanClass ,
176- Constructor <?> constructor , Class <?> declaringClass ) {
177-
174+ private CodeBlock generateCodeForAccessibleConstructor (String beanName , Constructor <?> constructor ) {
178175 this .generationContext .getRuntimeHints ().reflection ().registerConstructor (
179176 constructor , ExecutableMode .INTROSPECT );
180177
181178 if (constructor .getParameterCount () == 0 ) {
182179 if (!this .allowDirectSupplierShortcut ) {
183- return CodeBlock .of ("$T.using($T::new)" , InstanceSupplier .class , declaringClass );
180+ return CodeBlock .of ("$T.using($T::new)" , InstanceSupplier .class , constructor . getDeclaringClass () );
184181 }
185182 if (!isThrowingCheckedException (constructor )) {
186- return CodeBlock .of ("$T::new" , declaringClass );
183+ return CodeBlock .of ("$T::new" , constructor . getDeclaringClass () );
187184 }
188- return CodeBlock .of ("$T.of($T::new)" , ThrowingSupplier .class , declaringClass );
185+ return CodeBlock .of ("$T.of($T::new)" , ThrowingSupplier .class , constructor . getDeclaringClass () );
189186 }
190187
191188 GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod (method ->
192- buildGetInstanceMethodForConstructor (
193- method , beanName , beanClass , constructor , declaringClass , PRIVATE_STATIC ));
189+ buildGetInstanceMethodForConstructor (method , beanName , constructor , PRIVATE_STATIC ));
194190 return generateReturnStatement (generatedMethod );
195191 }
196192
197- private CodeBlock generateCodeForInaccessibleConstructor (String beanName , Class <?> beanClass ,
193+ private CodeBlock generateCodeForInaccessibleConstructor (String beanName ,
198194 Constructor <?> constructor , Consumer <ReflectionHints > hints ) {
199195
200196 CodeWarnings codeWarnings = new CodeWarnings ();
201- codeWarnings .detectDeprecation (beanClass , constructor )
197+ codeWarnings .detectDeprecation (constructor . getDeclaringClass () , constructor )
202198 .detectDeprecation (Arrays .stream (constructor .getParameters ()).map (Parameter ::getType ));
203199 hints .accept (this .generationContext .getRuntimeHints ().reflection ());
204200
205201 GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod (method -> {
206202 method .addJavadoc ("Get the bean instance supplier for '$L'." , beanName );
207203 method .addModifiers (PRIVATE_STATIC );
208204 codeWarnings .suppress (method );
209- method .returns (ParameterizedTypeName .get (BeanInstanceSupplier .class , beanClass ));
210- method .addStatement (generateResolverForConstructor (beanClass , constructor ));
205+ method .returns (ParameterizedTypeName .get (BeanInstanceSupplier .class , constructor . getDeclaringClass () ));
206+ method .addStatement (generateResolverForConstructor (constructor ));
211207 });
212208
213209 return generateReturnStatement (generatedMethod );
214210 }
215211
216- private void buildGetInstanceMethodForConstructor (MethodSpec .Builder method ,
217- String beanName , Class <?> beanClass , Constructor <?> constructor , Class <?> declaringClass ,
218- javax .lang .model .element .Modifier ... modifiers ) {
212+ private void buildGetInstanceMethodForConstructor (MethodSpec .Builder method , String beanName ,
213+ Constructor <?> constructor , javax .lang .model .element .Modifier ... modifiers ) {
214+
215+ Class <?> declaringClass = constructor .getDeclaringClass ();
219216
220217 CodeWarnings codeWarnings = new CodeWarnings ();
221- codeWarnings .detectDeprecation (beanClass , constructor , declaringClass )
218+ codeWarnings .detectDeprecation (declaringClass , constructor )
222219 .detectDeprecation (Arrays .stream (constructor .getParameters ()).map (Parameter ::getType ));
223220 method .addJavadoc ("Get the bean instance supplier for '$L'." , beanName );
224221 method .addModifiers (modifiers );
225222 codeWarnings .suppress (method );
226- method .returns (ParameterizedTypeName .get (BeanInstanceSupplier .class , beanClass ));
223+ method .returns (ParameterizedTypeName .get (BeanInstanceSupplier .class , declaringClass ));
227224
228225 CodeBlock .Builder code = CodeBlock .builder ();
229- code .add (generateResolverForConstructor (beanClass , constructor ));
226+ code .add (generateResolverForConstructor (constructor ));
230227 boolean hasArguments = constructor .getParameterCount () > 0 ;
228+ boolean onInnerClass = ClassUtils .isInnerClass (declaringClass );
231229
232230 CodeBlock arguments = hasArguments ?
233231 new AutowiredArgumentsCodeGenerator (declaringClass , constructor )
234- .generateCode (constructor .getParameterTypes ())
232+ .generateCode (constructor .getParameterTypes (), ( onInnerClass ? 1 : 0 ) )
235233 : NO_ARGS ;
236234
237235 CodeBlock newInstance = generateNewInstanceCodeForConstructor (declaringClass , arguments );
238236 code .add (generateWithGeneratorCode (hasArguments , newInstance ));
239237 method .addStatement (code .build ());
240238 }
241239
242- private CodeBlock generateResolverForConstructor (Class <?> beanClass , Constructor <?> constructor ) {
240+ private CodeBlock generateResolverForConstructor (Constructor <?> constructor ) {
243241 CodeBlock parameterTypes = generateParameterTypesCode (constructor .getParameterTypes ());
244- return CodeBlock .of ("return $T.<$T>forConstructor($L)" , BeanInstanceSupplier .class , beanClass , parameterTypes );
242+ return CodeBlock .of ("return $T.<$T>forConstructor($L)" , BeanInstanceSupplier .class ,
243+ constructor .getDeclaringClass (), parameterTypes );
245244 }
246245
247246 private CodeBlock generateNewInstanceCodeForConstructor (Class <?> declaringClass , CodeBlock args ) {
247+ if (ClassUtils .isInnerClass (declaringClass )) {
248+ return CodeBlock .of ("$L.getBeanFactory().getBean($T.class).new $L($L)" ,
249+ REGISTERED_BEAN_PARAMETER_NAME , declaringClass .getEnclosingClass (),
250+ declaringClass .getSimpleName (), args );
251+ }
248252 return CodeBlock .of ("new $T($L)" , declaringClass , args );
249253 }
250254
251255 private CodeBlock generateCodeForFactoryMethod (
252256 RegisteredBean registeredBean , Method factoryMethod , Class <?> targetClass ) {
253257
254- Visibility accessVisibility = getAccessVisibility (registeredBean , factoryMethod );
255- if (accessVisibility != Visibility .PRIVATE ) {
256- return generateCodeForAccessibleFactoryMethod (registeredBean .getBeanName (), factoryMethod , targetClass ,
257- registeredBean .getMergedBeanDefinition ().getFactoryBeanName ());
258+ if (!isVisible (factoryMethod , targetClass )) {
259+ return generateCodeForInaccessibleFactoryMethod (registeredBean .getBeanName (), factoryMethod , targetClass );
258260 }
259- return generateCodeForInaccessibleFactoryMethod (registeredBean .getBeanName (), factoryMethod , targetClass );
261+ return generateCodeForAccessibleFactoryMethod (registeredBean .getBeanName (), factoryMethod , targetClass ,
262+ registeredBean .getMergedBeanDefinition ().getFactoryBeanName ());
260263 }
261264
262265 private CodeBlock generateCodeForAccessibleFactoryMethod (String beanName ,
@@ -366,11 +369,13 @@ private CodeBlock generateWithGeneratorCode(boolean hasArguments, CodeBlock newI
366369 return code .build ();
367370 }
368371
369- private Visibility getAccessVisibility ( RegisteredBean registeredBean , Member member ) {
370- AccessControl beanTypeAccessControl = AccessControl .forResolvableType ( registeredBean . getBeanType () );
372+ private boolean isVisible ( Member member , Class <?> targetClass ) {
373+ AccessControl classAccessControl = AccessControl .forClass ( targetClass );
371374 AccessControl memberAccessControl = AccessControl .forMember (member );
372- return AccessControl .lowest (beanTypeAccessControl , memberAccessControl ).getVisibility ();
373- }
375+ Visibility visibility = AccessControl .lowest (classAccessControl , memberAccessControl ).getVisibility ();
376+ return (visibility == Visibility .PUBLIC || (visibility != Visibility .PRIVATE &&
377+ member .getDeclaringClass ().getPackageName ().equals (this .className .packageName ())));
378+ }
374379
375380 private CodeBlock generateParameterTypesCode (Class <?>[] parameterTypes ) {
376381 CodeBlock .Builder code = CodeBlock .builder ();
@@ -392,6 +397,7 @@ private boolean isThrowingCheckedException(Executable executable) {
392397 .anyMatch (Exception .class ::isAssignableFrom );
393398 }
394399
400+
395401 /**
396402 * Inner class to avoid a hard dependency on Kotlin at runtime.
397403 */
@@ -410,7 +416,6 @@ public static boolean hasConstructorWithOptionalParameter(Class<?> beanClass) {
410416 }
411417 return false ;
412418 }
413-
414419 }
415420
416421
0 commit comments