《spring》的Bean管理(上)

《spring》的Bean管理(上)

<大纲>

spring工厂类

spring三种实例化Bean的方式

Bean的配置

Bean的作用域

spring容器中Bean的生命周期

BeanPostProfessor的作用

1.spring的工厂类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q5P5p1Is-1609085042772)(F:\用户\个人\Desktop\QQ截图20201227212454.png)]

public class SpringDemo1 {

    @Test
    /**
     * 传统方式开发
     */
    public void demo1(){
        // UserService userService = new UserServiceImpl();
        UserServiceImpl userService = new UserServiceImpl();
        // 设置属性:
        userService.setName("张三");
        userService.sayHello();
    }

    @Test
    /**
     * Spring的方式实现
     */
    public void demo2(){
        // 创建Spring的工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类:
        UserService userService = (UserService) applicationContext.getBean("userService");

        userService.sayHello();
    }

    @Test
    /**
     * 读取磁盘系统中的配置文件
     */
    public void demo3(){
        // 创建Spring的工厂类:
        ApplicationContext applicationContext = new FileSystemXmlApplicationContext("c:\\applicationContext.xml");
        // 通过工厂获得类:
        UserService userService = (UserService) applicationContext.getBean("userService");

        userService.sayHello();
    }

    @Test
    /**
     * 传统方式的工厂类:BeanFactory
     */
    public void demo4(){
        // 创建工厂类:
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
        // 通过工厂获得类:
        UserService userService = (UserService) beanFactory.getBean("userService");

        userService.sayHello();
    }

    /**
     * 传统方式的工厂类:BeanFactory
     */
    @Test
    public void demo5(){
        // 创建工厂类:
        BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("c:\\applicationContext.xml"));
        // 通过工厂获得类:
        UserService userService = (UserService) beanFactory.getBean("userService");

        userService.sayHello();
    }
}

ApplicationContext在创建工厂,加载配置文件的时候就会实例化单例模式的工厂

2.spring三种实例化Bean的方式

  • 使用类构造器实例化(默认无参数)(经常使用)

    /**
     * Bean的实例化的三种方式:采用无参数的构造方法的方式
     */
    public class Bean1 {
        public Bean1(){
            System.out.println("Bean1被实例化了...");
        }
    }
    
    @Test
        public void demo1() {
            // 创建工厂
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            // 通过工厂获得类的实例:
            Bean1 bean1 = (Bean1)applicationContext.getBean("bean1");
        }
    
    <!--第一种:无参构造器的方式-->
        <!--<bean id="bean1" class="com.imooc.ioc.demo2.Bean1"/>-->
    
  • 使用静态工厂方法实例化(简单工厂模式)

     * Bean的实例化三种方式:静态工厂实例化方式
     */
    public class Bean2 {
    
    }
    
    /**
     * Bean2的静态工厂
     */
    public class Bean2Factory {
    
        public static Bean2 createBean2(){
            System.out.println("Bean2Factory的方法已经执行了...");
            return new Bean2();
        }
    
    }
    
    <!--第二种:静态工厂的方式-->
        <!--<bean id="bean2" class="com.imooc.ioc.demo2.Bean2Factory" factory-method="createBean2"/>-->
    
  • 使用实例工厂方法实例化(工厂方法模式)

    /**
     * Bean的实例化三种方式:实例工厂实例化
     */
    public class Bean3 {
    
    }
    
    /**
     * Bean3的实例工厂
     */
    public class Bean3Factory {
        public Bean3 createBean3(){
            System.out.println("Bean3Factory执行了...");
            return new Bean3();
        }
    }
    
    <!--第三种:实例工厂的方式-->
        <!--<bean id="bean3Factory" class="com.imooc.ioc.demo2.Bean3Factory"/>
        <bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"/>-->
    

3.Bean的配置

  • id和name
    • 一般情况下,装配一个Bean时,通过指定id属性作为Bean的名称
    • id属性在IOC容器中必须是唯一的
    • 如果Bean的名称有特殊字符,就需要使用name属性替换id属性
  • class
    • class用于设置一个类的完全路径名称,主要作用是IOC容器生成类的实例

4.Bean的作用域

  • 单例模式:scope=“singleton”
public class Person {

}
@Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person persion1 = (Person)applicationContext.getBean("person");
        Person persion2 = (Person)applicationContext.getBean("person");

        System.out.println(persion1);
        System.out.println(persion2);
    }

地址一样

    <!--单例模式,默认情况下也是 -->
    <!--<bean id="person" class="com.imooc.ioc.demo3.Person" scope="singleton"/>-->
  • 多例模式
    <!--多例模式-->
    <bean id="person" class="com.imooc.ioc.demo3.Person" scope="prototype"/>

地址不同,每次getBean(),都获得一个新的对象

4.spring容器中Bean的生命周期

spring初始化Bean或者销毁Bean的时候,有时需要做一些处理工作,因此spring可以在创建和拆卸Bean的时候调用两个生命周期方法。

销毁方法只有spring在单例模式下才有效

<bean id="man" class="com.imooc.ioc.demo3.Man" init-method="setup" destroy-method="teardown">
public class Man {
    public Man() {
        System.out.println("Man被实例化了");
    }
    public void setup() {
        System.out.println("Man被初始化了");
    }
    public void teardown {
        System.out.println("Man被销毁了");
    }
}
@Test
    public void demo2(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Man man = (Man)applicationContext.getBean("man");

        man.run();

        applicationContext.close();
    }

![在这里插入图片描述](https://img-blog.csdnimg.cn/20201228000656897.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzQ3NjAzMDEy,size_16,color_FFFFFF,t_70#pic_center)


1. instantiate bean对象实例化
2. populate properties封装属性
3. 如果Bean实现BeanNameAware执行setBeanName
4. 如果Bean实现BeanFactoryAware 或者ApplicationContextAware设置工厂setBeanFactory或者上下文对象setApplicationContext
5. 如果存在类实现 BeanPostProcessor (后处理Bean ),执行
   postProcessBeforeInitialization
6. 如果Bean实现InitializingBean执行afterPropertiesSet
7. 调用<bean init-method="init">指定初始化方法 init如果
8. 存在类实现BeanPostProcessor (处理Bean ) ,执行postProcessAfterInitialization8.如果存在类实现BeanPostProcessor (处理Bean ),执行
   postProcessAfterInitialization
9. 执行业务处理
10. 如果Bean实现 DisposableBean 执行destroy
11. 调用<bean destroy-method="customerDestroy">指定销毁方法customerDestroy

```java
public class Man implements BeanNameAware,ApplicationContextAware,InitializingBean,DisposableBean{
    private String name;

    public void setName(String name) {
        System.out.println("第二步:设置属性");
        this.name = name;
    }

    public Man(){
        System.out.println("第一步:初始化...");
    }
    public void setup(){
        System.out.println("第七步:MAN被初始化了...");
    }

    public void teardown(){
        System.out.println("第十一步:MAN被销毁了...");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("第三步:设置Bean的名称"+name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("第四步:了解工厂信息");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("第六步:属性设置后");
    }

    public void run(){
        System.out.println("第九步:执行业务方法");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("第十步:执行Spring的销毁方法");
    }
}

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //System.out.println("第五步:初始化前方法...");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        //System.out.println("第八步:初始化后方法...");
    }		
   <bean id="man" class="com.imooc.ioc.demo3.Man" init-method="setup" destroy-method="teardown">
        <property name="name" value="张三"/>
    </bean>
<bean class="com.imooc.ioc.demo3.MyBeanPostProcessor"/>

5.BeanPostProfessor的作用

对生成的类产生代理,并且对里面的方法产生增强

@Test
    public void demo3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao)applicationContext.getBean("userDao");

        userDao.findAll();
        userDao.save();
        userDao.update();
        userDao.delete();

    }
package com.imooc.ioc.demo3;

public interface UserDao {
    public void findAll();

    public void save();

    public void update();

    public void delete();
}

package com.imooc.ioc.demo3;

public class UserDaoImpl implements  UserDao {
    @Override
    public void findAll() {
        System.out.println("查询用户。。。");
    }

    @Override
    public void save() {
        System.out.println("保存用户。。。");
    }

    @Override
    public void update() {
        System.out.println("修改用户。。。");
    }

    @Override
    public void delete() {
        System.out.println("删除用户。。。");
    }
}

<bean id="userDao" class="com.imooc.ioc.demo3.UserDaoImpl"/>
package com.imooc.ioc.demo3;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //System.out.println("第五步:初始化前方法...");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        //System.out.println("第八步:初始化后方法...");
        if("userDao".equals(beanName)){
            Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if("save".equals(method.getName())){
                        System.out.println("权限校验===================");
                        return method.invoke(bean,args);
                    }
                    return method.invoke(bean,args);
                }
            });
            return proxy;
        }else{
            return bean;
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值