类的构造方法创建普通对象-->依赖注入(IOC注入依赖的bean对象)-->初始化前-->初始化-->初始化后(通过AOP生成代理对象)-->代理对象-->放入单例Map(beanFactory)-->bean对象
初始化前的实现和逻辑: 在初始化前的方法上添加注解 @PostConstruct
for(Method method:userServiceN.getClass().getMethods()){ //方法是否有 PostConstruct 这个注解 if(method.isAnnotationPresent(PostConstruct.class)){ try { method.invoke(userServiceN); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
初始化的实现和逻辑:实现InitializingBean接口中的方法afterPropertiesSet
if( orderService instanceof InitializingBean){ try { orderService.afterPropertiesSet(); } catch (Exception e) { e.printStackTrace(); } }
初始化后的实现和逻辑:定义切面类添加@Aspect,在@Before和@After中指定方法执行前后的织入
@Aspect @Component public class TestAspect { @Before("execution(public void com.example.demo.service.UserService.b())") public void before(JoinPoint joinPoint){ joinPoint.getTarget(); //获得依赖注入后的对象,不是bean System.out.println("初始化前"); } @After("execution(public void com.example.demo.service.UserService.b())") public void after(JoinPoint joinPoint){ System.out.println("初始化后"); } }
bean的注入:
@Autowired先 byType 再 byName,根据byType找到一个bean就不会再byName查找
一个接口多个实现类时注入不同的bean:
(1)、使用@Qualifier注解指定要注入的beanName
(2)、声明bean的名称和要注入的对象名称一样
正常情况下一个类只会有一个bean,以下代码会产生name为userServiceImpl1和userServiceImpl2的两个bean(实现同一个接口),根据name注入时如果name不正确就报错
@Resource注入:
如果没有指定name属性,spring容器启动时根据属性名查找bean,找不到报错;
使用name属性,如果name属性名称错误就报错了;