基于ImportSelector模拟简单的Aop
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection<SourceClass> importCandidates, boolean checkForCircularImports) { if (importCandidates.isEmpty()) { return; } if (checkForCircularImports && isChainedImportOnStack(configClass)) { this.problemReporter.error(new CircularImportProblem(configClass, this.importStack)); } else { this.importStack.push(configClass); try { for (SourceClass candidate : importCandidates) { //处理ImportSelector if (candidate.isAssignable(ImportSelector.class)) { // Candidate class is an ImportSelector -> delegate to it to determine imports Class<?> candidateClass = candidate.loadClass(); ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class); s); //如果该接口的实现类同时实现EnvironmentAware, BeanFactoryAware ,BeanClassLoaderAware或者ResourceLoaderAware,那么在调用其selectImports方法之前先调用上述接口中对应的方法 ParserStrategyUtils.invokeAwareMethods( selector, this.environment, this.resourceLoader, this.registry); //如果是deferredImportSelectors类型,代表需要延时处理,先暂时放到List<DeferredImportSelectorHolder> deferredImportSelectors中,等到所有的@Configuration处理完,最后面才处理实现了DeferredImportSelector接口的类 if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) { this.deferredImportSelectors.add( new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector)); } else { String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames); processImports(configClass, currentSourceClass, importSourceClasses, false); } } //处理ImportBeanDefinitionRegistrar else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) { // Candidate class is an ImportBeanDefinitionRegistrar -> // delegate to it to register additional bean definitions Class<?> candidateClass = candidate.loadClass(); ImportBeanDefinitionRegistrar registrar = BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class); ParserStrategyUtils.invokeAwareMethods( registrar, this.environment, this.resourceLoader, this.registry); configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); } //处理普通的配置类 else { // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar -> // process it as an @Configuration class this.importStack.registerImport( currentSourceClass.getMetadata(), candidate.getMetadata().getClassName()); processConfigurationClass(candidate.asConfigClass(configClass)); } } } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", ex); } finally { this.importStack.pop(); } }
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
public interface IUserDao { void query(); }
@Repository public class UserDao implements IUserDao { public void query() { System.out.println("from db....."); } }
public class MyAop implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("userDao")) { bean = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{IUserDao.class}, new MyInvokeHandler(bean)); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } } public class MyInvokeHandler implements InvocationHandler { Object target; public MyInvokeHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("proxy 方法"); return method.invoke(target, args); }
}
public class MyImportSelect implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{com.tian.util.MyAop.class.getName() }; } }
@Retention(RetentionPolicy.RUNTIME) @Import(MyImportSelect.class) public @interface EanableAop { }
@Configuration @ComponentScan("com.tian") @EanableAop public class AppConfig {}
@Test public void test_import() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); String[] names = context.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } IUserDao dao = (IUserDao) context.getBean("userDao"); dao.query(); }
最终结果,当然如果把