介面動態代理IOC注入到spring容器中
阿新 • • 發佈:2021-06-16
public interface StudentService { public void add(String studentName); }
定義一個spring的FactoryBean,FactoryBean在通過spring例項化生成的不是自己本身,而是通過呼叫的getObject方法返回的物件,該FactoryBean為介面生成一個動態代理的實現。
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; importorg.springframework.beans.factory.FactoryBean; public class StudentServiceFactoryBean implements FactoryBean<StudentService>{ private String studentName; @Override public StudentService getObject() throws Exception { //生成資料庫訪問代理(相當於Mapper的代理) StudentService studentService = (StudentService)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class<?>[]{StudentService.class}, new MapperInvocationHandler(studentName)); return studentService; } @Override public Class<?> getObjectType() { return StudentService.class; } public String getStudentName() { return studentName; }public void setStudentName(String studentName) { this.studentName = studentName; } public static class MapperInvocationHandler implements InvocationHandler{ private String mapperName; public MapperInvocationHandler(String mapperName) { super(); this.mapperName = mapperName; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String sql = method.getName(); if (sql.equals("add")) { System.out.println(mapperName+"execute add method"+args[0]); } return null; } } }
把該FactoryBean注入到Spring的BeanDefinitionRegistry中:
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { try { BeanDefinition sbd = new RootBeanDefinition(StudentServiceFactoryBean.class); sbd.getPropertyValues().addPropertyValue("studentName", "zhangsan"); BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(sbd ,"StudentService"); BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry); }catch(Exception e) { } } }
測試程式碼:
@Component public class MyIncludeBean implements InitializingBean{ @Autowired private StudentService studentService; @Override public void afterPropertiesSet() throws Exception { System.out.println("MyIncludeBean:init"); studentService.add("student111"); } }
控制檯成功列印:
MyIncludeBean:init
zhangsanexecute add methodstudent111