
IOC的底层原理:XML解析+工厂模式+反射
- public class UserService {
- /**
- * 之前想要在一个类中使用另一个类的实例方法,就必须创建此类的对象,然后调用,
- * 但是这样的话,两个类的耦合度就太高了,如果实现类要换了,
- * 所有类用到了这个实现类的都要改,这里的new UserDao();都得改,
- * 改的话就意味着要重新编译,打包,部署,这样耗费的人力就太多了.
- *
- * 于是spring就站出来,提出一种解决方案:IOC控制反转.
- * spring说不要将对象定死了,就是不要程序员自己创建对象了,程序员只需要声明即可,
- * 对象由spring创建,然后放在容器中供我们使用.
- */
- // private UserDao userDao = new UserDaoImpl(); 不要自己创建对象
-
- @Autowired
- private UserDao userDao;// 只需声明即可,这样代码就不用修改了
-
- public int addUser(){
-
- int add = userDao.add();
- return add;
- }
- }
-
-
- <bean id="userDao" class="com.lin.ioc.dao.impl.UserDaoImpl"/>
1、首先就是bean实例化,调用bean的无参或有参构造器创建对象。
2、调用setter方法给bean对象的属性赋值,如果第一步是调用有参的构造器创建对象,这步就没有。
3、spring调用Aware接口中的方法,凡是实现了Aware接口的类,都会执行接口中的方法
- /**
- * User bean
- *
- * BeanFactory, ApplicationContext等对象是spring容器的内置对象,不是程序员定义的。
- * 如果想要在一个bean中使用这些对象的话,可以在bean中声明想要的容器内置对象:private ApplicationContext applicationContext;
- *
- * 然后实现xxxAware接口,实现接口的方法,这样在bean初始化的时候,spring会调用xxxAware接口的setXXX(XXX xxx),将你想要对象作为方法的对象传过来,
- * 然后你就可以用这个对象了。
- *
- * @author shkstart
- * @create 2022-09-05 11:33
- */
- public class User implements ApplicationContextAware {
-
- // 在一个bean中想要用ApplicationContext对象,
- private ApplicationContext applicationContext;
-
- // applicationContext对象spring调用这个方法的时候会传过来
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- System.out.println("2、Aware接口的setApplicationContext()给User对象的applicationContext属性赋值...");
-
- this.applicationContext = applicationContext;
- }
-
- }
4、bean初始化前置处理:spring调用BeanPostProcessor接口中的postProcessBeforeInitialization(Object bean, String beanName)
bean就是你的bean对象,beanName是你的bean对象的name,这是你就可以对你的bean对象做任何操作,这个阶段是为了给你的bean一些扩展处理。
如果你想对你的bean对象在初始化前做一些自定义的处理,就可以实现BeanPostProcessor接口,并实现postProcessBeforeInitialization(Object bean, String beanName)方法。
5、执行InitializingBean接口中的afterPropertiesSet()方法
看方法名是在属性设置完后,就是在bean对象属性设置完之后由spring调用,和上面那个初始化前置处理区别就只是,这个方法没有参数,不能对bean对象做处理,只能做一些额外的逻辑处理。想要用,bean类要实现InitializingBean接口。
6、执行程序员自定义的初始化方法。
- // 自定义初始化方法
- @PostConstruct
- public void initUser(){
- System.out.println("User对象初始化时,执行...");
- }
7、 bean初始化后置处理:执行BeanPostProcessor接口中的postProcessAfterInitialization(Object bean, String beanName)方法。
如果你想对你的bean对象在初始化后做一些自定义的处理,就可以实现BeanPostProcessor接口,并实现postProcessAfterInitialization(Object bean, String beanName)方法。
8、经过上面的3~7的bean初始化,这个时候bean就可以使用了,使用完了如果容器关闭,就进入bean销毁阶段。
1)bean销毁前置处理:执行DestructionAwareBeanPostProcessor接口中的postProcessBeforeDestruction(Object bean, String beanName)方法,如果想要在bean销毁前对bean对象做一些处理,可以实现这个接口。
2)执行自定义的销毁方法,不想在销毁前对bean对象做处理,只是做一些额外的业务处理,可以自定义销毁方法,不带参数。
- // 自定义销毁回调方法
- @PreDestroy
- public void destroyUser(){
- System.out.println("容器关闭,User对象销毁前...");
- }

