Spring---IOC学习

不管是注解注入还是在xml文件中配置Bean注入的本质利用反射创建实例对象

一、静态工厂 | | 实例工厂、Spring的工厂类

1、静态工厂 | | 实例工厂

       静态工厂:只需要直接调用工厂类的静态方法,不需要new对象。

	public class BeanStaticFactory {
	
	    public static Car getBean() {
	        Car car = new Car("雷克萨斯", 110);
	        return car;
	    }
	}

       实例工厂:需要new对象,再用对象调方法。


	public class BeanInstanceFactory {
	
	    public Car getBean() {
	        Car car = new Car("本田", 90);
	        return car;
	    }
	}

XML配置:
<bean class="cj.factory.BeanStaticFactory" id="f1" factory-method="getBean" scope="prototype"></bean>
测试结果(以静态工厂举例,和实例工厂差不多):
Alt
XML配置(默认是单例对象):
<bean class="cj.factory.BeanStaticFactory" id="f1" factory-method="getBean"></bean>
测试结果(以静态工厂举例,和实例工厂差不多):
Alt
       总结:自己写的静态工厂和实例工厂,在容器中初始化的时机和之前的bean一样。假如是单例对象,那么在容器创建前就初始化进IOC容器;多例对象则容器创建前不会进入容器,当该对象被获取的时候才进入Spring的容器中。

2、Spring的工厂类

       spring的工厂类:实现了FactoryBean<T>的接口。

	public class MyFactoryBean implements FactoryBean<Car> {
	
	    public Car getObject() throws Exception {
	        Car car = new Car("福特", 100);
	        return car;
	        //返回值不能是空, 相当于这个方法代理了getBean方法。
	        //如果返回值为空了, getBean就获取不到对象了。
	    }
	
	    public Class<?> getObjectType() {
	        return Car.class;
	    }
	
	    public boolean isSingleton() {
	        return true;
	    }
	}

       isSingleton函数返回为true测试结果:
Alt
       isSingleton函数返回为false测试结果:
Alt
       总结:实现了FactoryBean的Bean,不管是单例还是多例,都是在容器创建后才放进Spring的IOC容器中的。

3、BeanFactory和FactoryBean的区别

BeanFactory直译过来就是Bean的工厂,他是一个工厂类,在Spring容器中所有的Bean都是由BeanFactory(IOC容器)管理的。 但是FactoryBean还是个Bean,不过是个特殊的工厂Bean。



二、后置处理器

偏源码的解释:
       ApplicationContext会自动检测在配置文件中实现了BeanPostProcessor接口的所有bean,并把它们注册为后置处理器。

bean的后置处理器和bean标签的init-method属性执行顺序为:
       1、执行BeanPostProcessor接口中的before方法(postProcessBeforeInitialization—初始化前方法),
       2、后执行init-method方法,
       3、最后执行after方法(postProcessAfterInitialization—初始化后方法)。

一些Spring AOP的底层处理也是通过实现bean后置处理器来执行代理包装逻辑。

我们定义一个类实现了BeanPostProcessor,默认是会对整个Spring容器中所有的bean进行处理。



三、注解与自动装配

1、注解

       注解注入的本质:利用反射创建实例对象

① 注解注入

       注解注入:@Repository、@Service、@Controller、@Component

       持久层用的Repository注解、业务层用的Service注解、控制层用的Controller注解。

       上面三个注解都实现了Component注解接口。所以扫描包的时候指定注解配置,且注解类型是Component的时候,上述注解都会添加到Spring的IOC容器中

	@Component
	public class TestDemoZhujie {
	
	}

       单单通过注解注入某个Bean到IOC容器后,该Bean默认的id是原来首字母改为小写的类名。也可以通过注解的value属性修改该id,当注解中只写了value属性的时候,value可以省略不写。

② 修改单例、多例

       默认是单例对象,通过@Scope(value = "prototype")修改为多例对象。

2、自动装配

       自动装配:只能装自定义的对象。自动为这个Bean装配成员变量,前提是装配的变量已经在容器中了。且必须要有对应成员变量的set和get方法,否则注入为空。

① XML配置
	<bean class="cj.entity.Car" id="car3" init-method="init" destroy-method="destroy">
        <property name="carSpeed" value="666"></property>
        <property name="carName" value="奔驰"></property>
    </bean>
    
    <bean class="cj.entity.Person" id="p1" autowire="byName"></bean>

       测试结果:
Alt
       结果表明自动装配成功。

② 注解配置
	@Controller
	public class UserServlet {
	
	    @Autowired
	    private UserService userService;
	
	    public void add() {
	        userService.add();
	    }
	
	    @Autowired
	    public void run(@Qualifier("userDao2") UserDao userDao, UserService userService) {
	        System.out.println("66666666" + userDao + "---" + userService);
	    }
	}

       @Autowired(注在成员变量上):自动以成员变量的类型去容器中寻找Bean,找不到就报错。如果匹配多个,则按照当前Bean的成员变量的名字作为id去Spring的IOC容器中寻找Bean,没找到就报错。Autowired注解一出场,就必须找到,可以通过指定属性@Autowired(required = false)找不到就为null。不需要set和get方法就可以成功注入,只要装配的变量在Spring的IOC容器中即可。

       @Autowired(注在成员方法上):将从容器中自动装配方法参数。并且这个方法也会在创建Bean的时候自动运行。

       @Qualifier:一般和Autowired注解连用,当默认的找不到的时候,指定寻找的Bean的id。也可以注在方法参数上。

发布了33 篇原创文章 · 获赞 5 · 访问量 2291

猜你喜欢

转载自blog.csdn.net/cj1561435010/article/details/103956379
今日推荐