关于spring,总结了一篇上万字的图文笔记,不管你工作几年都应该看看。

spring bean的实例化

构造器实例化

 <!--
        无参构造器实例化
    -->
    <bean id="student1" class="com.qfedu.entity.Student">
        <property name="id" value="100"></property>
        <property name="name" value="xiaoming"></property>
    </bean>

静态工厂实例化

容器创建对象,不直接调用对象构造方法,而是调用静态工厂的创建对象的方法
好处:便于我们定制化创建对象,对象的初始化,需要访问网络中的数据

/**
 * 静态工厂
 *    静态方法创建对象
 */
public class StaticFactory {


    /**
     * 静态方法 创建对象
     * @return
     */
    public static Student createStudent(){

        Student student = new Student();

        
        // 好处就是 程序员可以 自定义 初始化对象,并交给spring容器创建 
        student.setId(123);
        student.setName("小明");

        return  student;
    }

}

<!--
       告诉容器使用静态工厂 创建对象
        class="com.qfedu.factory.StaticFactory" 静态工厂
        factory-method="createStudent" 调用静态工厂的方法名
    -->
    <bean id="student2" class="com.qfedu.factory.StaticFactory" factory-method="createStudent">

    </bean>

个人整理了一些资料,有需要的朋友可以直接点击领取。

Java基础知识大全

22本Java架构师核心书籍

从0到1Java学习路线和资料

1000+道2021年最新面试题

实例工厂实例化

/**
 * 实例工厂 创建对象
 */
public class Factory {


    /**
     * 实例方法 创建对象
     * @return
     */
    public  Student createStudent(){

        Student student = new Student();


        // 好处就是 程序员可以 自定义 初始化对象,并交给spring容器创建
        student.setId(123);
        student.setName("小明");

        return  student;
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--
        创建实例工厂
    -->
    <bean id="factory" class="com.qfedu.factory.Factory">

    </bean>
    <!--
            目标创建 student  使用实例工厂
                factory-bean="factory" 引用实例工厂
                factory-method="createStudent" 调用实例工厂中的实例 方法
    -->
    <bean id="student" factory-bean="factory" factory-method="createStudent">

    </bean>

</beans>

工厂实例化的使用场景

工厂实例化作用:便于程序员自定义创建对象
使用场景:初始化数据库数据时,对数据库密码进行解密,将数据源放置到容器中,提高安全性

bean的作用域

作用域:就是bean 在容器中生存的范围
常用的:单例,原型


单例模式

<!--
       让容器创建一个student
       默认 该bean 作用域 是单例singleton  scope="singleton"
             单例singleton 无论用户是否获取该bean,容器在启动创建该bean,而且只创建一个 对应bean id为 student
   -->
   <bean id="student" class="com.qfedu.entity.Student" scope="singleton">
       <property name="id" value="100"></property>
       <property name="name" value="xiaoming"></property>
   </bean>


原型测试


    <!--
        告诉容器创建一个 原型 bean  id="student1"
        什么时候创建? 容器启动不创将该bean,在用户获取时创建,而且每获取一次创建一个bean,容器只负责创建,
        不负责持有,管理该bean
    -->
    <bean id="student1" class="com.qfedu.entity.Student" scope="prototype">
        <property name="id" value="100"></property>
        <property name="name" value="xiaoming"></property>
    </bean>

测试

public class ScopeTest {
    public static void main(String[] args) {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scope/scope_bean.xml");

        System.out.println("单例测试");
        //单例的bena无论获取多少次都是单例
        Student student1 = (Student) applicationContext.getBean("student");

        Student student2 = (Student) applicationContext.getBean("student");

        System.out.println("student1 == student2:" + (student1 == student2));

        System.out.println("*********");
        System.out.println("原型测试");
        // 获取 原型bean, 每次获取都是一个新的对象,容器只负责创建,不负责持有,维护
        Student student3 = (Student) applicationContext.getBean("student1");

        Student student4 = (Student) applicationContext.getBean("student1");

        System.out.println("student3 == student4:" + (student3 == student4));
    }
}


bean的生命周期

bean:交给容器维护,容器管理bean
bean的生命周期 的bean 的作用域相关

singleton

Spring容器可以管理singleton作用域的Bean的生命周期,在此作用域下,Spring能够精确的知道该Bean何时被创建,何时初始化完成,以及何时被销毁。

容器创建bean,管理bean
容器初始化时创建 单例的 bean,并且持有bean, 容器销毁时 ,销毁bean

prototype

prototype作用域的Bean,Spring只负责创建,当容器创建了Bean实例后,Bean的实例就交给客户端代码来管理,Spring容器将不再跟踪其生命周期。

容器只创建bean不管理
容器初始化时,不会创建bean,只有在获取时才会创建bean,spring 只负责创建,不持有bean,也不负责销毁,还可以为bean 配置 init()初始化方法,destroy() 销毁方法

public class Student implements Serializable {

    private int id;

    private String name;

    /**
     * 初始化 资源
     */
    public void  init(){

        System.out.println("Student 初始化方法");
    }

    /**
     * 释放资源
     */
    public void destroy(){
        System.out.println("Student 销毁方法");
    }
。。。。
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
        单例bean scope="singleton"

              init-method="init" bean 在创建时调用 初始化方法
              destroy-method="destroy" 容器销毁 方法
    -->

    <bean id="student1" class="com.qfedu.entity.Student" scope="singleton"
          init-method="init" destroy-method="destroy">
        <property name="id" value="100"></property>
        <property name="name" value="xiaoming"></property>
    </bean>



    <!--
    原型bean scope="prototype"

          init-method="init" bean 在创建时调用 初始化方法
          destroy-method="destroy" 容器销毁 方法
-->
    <bean id="student2" class="com.qfedu.entity.Student" scope="prototype"
          init-method="init" destroy-method="destroy">
        <property name="id" value="100"></property>
        <property name="name" value="张三"></property>
    </bean>
</beans>

测试:

/**
 *bena的生命周期
 */
public class LifeTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext classPathXmlApplicationContext  = new ClassPathXmlApplicationContext("life/life_bean.xml");

        Student student1 = (Student) classPathXmlApplicationContext.getBean("student1");

        System.out.println(student1);
        System.out.println("容器销毁");

        // 明示销毁容器,此时会调用容器中所有bean destroy() 方法
        // 单例bean 调用 destroy()
        // 原型bean  不会调用 destroy()  因为容器不持有该bean
        classPathXmlApplicationContext.destroy();
    }
}

Bean的装配

什么Bean的装配?
就是bean 属性的设置,以及bean 之间依赖关系的配置

基于XML的装配

property和构造方法设置值(无参和有参)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--
         通过无参构造 使用setter 初始化bean
    -->
    <bean id="student1" class="com.qfedu.entity.Student">
        <property name="id" value="100"></property>
        <property name="name" value="xiaoming"></property>
        <property name="sex" value="F"></property>

        <property name="course" >

            <list>
                <value>Java</value>
                <value>UI</value>
                <value>H5</value>
                <value>php</value>
            </list>
        </property>
    </bean>

    <!--
        通过有参构造创建  bean
        public Student(int id, String name, String sex, List<String> course)
                            0        1               2          3
                            
          <constructor-arg index="0" value="111"></constructor-arg> 为每一个构造方法的参数设置
          属性                     
     -->
    <bean id="student1" class="com.qfedu.entity.Student">

        <constructor-arg index="0" value="111"></constructor-arg>
        <constructor-arg index="1" value="zhangsan"></constructor-arg>
        <constructor-arg index="2" value="F"></constructor-arg>
        <constructor-arg index="3" >
            
            <list>
                <value>Java</value>
                <value>UI</value>
                <value>H5</value>
                <value>php</value>
            </list>
        </constructor-arg>
    </bean>

</beans>

测试

public class XmlTest {
    public static void main(String[] args) {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("xml/xml_bean.xml");

        Student student1 = (Student) applicationContext.getBean("student1");
        System.out.println("student1 = " + student1);

        Student student2 = (Student) applicationContext.getBean("student2");
        System.out.println("student2 = " + student2);
    }
}

基于注解的装配

注解:就是一个标记,记号
通过注解创建bean 并管理bean 之间的依赖关系

注入的注解
一个实例中的属性可以通过以下注解从容器获取对应的bean,并注入进来:

@Autowired:用于对Bean的属性变量、属性的setter方法及构造方法进行标注,配合对应的注解处理器完成Bean的自动配置工作

@Qualifier:与@Autowired注解配合使用,会将默认的按Bean类型装配修改为按Bean的实例名称装配,Bean的实例名称由@Qualifier注解的参数指定。

@Resource:其作用与Autowired一样。@Resource中有两个重要属性:name和type。Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型。

@Autowired + @Qualifier

激活注入的注解:

 <!--

        这是一个开关,激活 @Autowired    @ Resource 、@ PostConstruct、@ PreDestroy
                       让他们生效
    -->
    <context:annotation-config></context:annotation-config>

加入注解到容器中:

<!--
       将StudentDaoImpl加入到容器中StudentDaoImpl
   -->
    <bean id="studentDao1" class="com.qfedu.dao.StudentDaoImpl"></bean>
    <bean id="studentDao2" class="com.qfedu.dao.StudentDaoImpl"></bean>

    <!--
       将StudentServiceImpl加入到容器中
   -->
    <bean id="studentService" class="com.qfedu.service.StudentServiceImpl"></bean>

装配:

public class StudentServiceImpl implements StudentService{


    /*@Autowired 不需要 setter方法支持
     * 意义: 1.首先根据注解的类型 去容器中查找 如果只有一个,则设置
     *       2.如果按照类型查找到 多个 ,则使用 变量名( private StudentDao studentDao) 作为id 去容器中查找
     *       3.如果按照变量名找不到,可以使用@Qualifier("studentDao2") 配置,按照传递的参数作为iD 查找
     */

    // 去容器中查找 StudentDao 对应实例,并将当前 属性引用
    @Autowired
    @Qualifier("studentDao2")//如果找到多个使用  @Qualifier区分
    private StudentDao studentDao;

//    public void setStudentDao(StudentDao studentDao){
//        this.studentDao = studentDao;
//    }

    public Student findStudentById(int id) {
        return studentDao.findStudentById(id);
    }
}

@Resource

激活注入的注解:

 <!--

        这是一个开关,激活 @Autowired    @ Resource 、@ PostConstruct、@ PreDestroy
                       让他们生效
    -->
    <context:annotation-config></context:annotation-config>

加入注解到容器中:


    <!--
       将StudentDaoImpl加入到容器中StudentDaoImpl
   -->
    <bean id="studentDao1" class="com.qfedu.dao.StudentDaoImpl"></bean>
    <bean id="studentDao2" class="com.qfedu.dao.StudentDaoImpl"></bean>

    <!--
       将StudentServiceImpl加入到容器中
   -->
    <bean id="studentService" class="com.qfedu.service.StudentServiceImpl"></bean>

装配:

public class StudentServiceImpl implements StudentService{


    /*
     *  @Resource  也是 将容器中的bean 注入到当前对象中
     * 意义:
     *      1.首先按照声明 属性名作为id 去容器中查找(private StudentDao studentDao ),
     *      2.如果没有找到 按照类型查找 ,如果查找到一个则设置值, 如果查到多个,则进入第三步
     *      3.@Resource(name = "studentDao2"): 如果找到多个类型的bean 必须传入name 作为id 进行限定
     *
     * @Autowired    @Resource 的区别?
     *
     * 1. @Resource(name = "studentDao2") 等价于 @Autowired  @Qualifier
     * 2.意义
     * 3.@Resource 是jdk 注解 @Autowired 是spring 注解
    * */

    @Resource(name = "studentDao2")
    private StudentDao studentDao;

//    public void setStudentDao(StudentDao studentDao){
//        this.studentDao = studentDao;
//    }

    public Student findStudentById(int id) {
        return studentDao.findStudentById(id);
    }
}


总结

@Autowired 不需要 setter方法支持

  • 意义: 1.首先根据注解的类型 去容器中查找 如果只有一个,则设置
  • 2.如果按照类型查找到 多个 ,则使用 变量名( private StudentDao studentDao) 作为id 去容器中查找
  • 3.如果按照变量 名找不到,可以使用@Qualifier(“studentDao2”) 配置,按照传递的参数作为iD 查找
  • @Resource 也是 将容器中的bean 注入到当前对象中
  • 意义:
  • 1.首先按照声明 属性名作为id 去容器中查找(private StudentDao studentDao ),
  • 2.如果没有找到 按照类型查找 ,如果查找到一个设置值 如果多个,则进入第三部
  • 3.@Resource(name = “studentDao2”) 如果找到多个类型的bean 必须传入name 作为id 进行限定
  • @Autowired @Resource 的区别?
    1. @Resource(name = “studentDao2”) 等价于 @Autowired @Qualifier
  • 2.意义
  • 3.@Resource 是jdk 注解 @Autowired spring 注解

生成bean的注解

@Component
//@Component // 在容器中加入bean 默认id studentServiceImpl
@Component(“studentService”) // 在容器中加入bean id studentService
以下三个用法和 @Component 一样是@Component 的子注解
@Service 用于service
@Controller 用于控制层
@Repository 用于持久层 dao


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


    <!--
        包扫描器 :
        激活 注入注解   @Autowired    @ Resource
        激活生成bean 的注解
            @Component
                    //@Component // 在容器中加入bean 默认id  studentServiceImpl
                    @Component("studentService")   // 在容器中加入bean id  studentService
            以下三个用法和 @Component 一样是@Component 的子注解
            @Service   用于service
            @Controller 用于控制层
            @Repository  用于持久层 dao
    -->
    <context:component-scan base-package="com.qfedu"></context:component-scan>


</beans>

//@Component // 在容器中加入bean 默认id  studentServiceImpl
//@Component("studentService")   // 在容器中加入bean id  studentService
@Service("studentService")// 加入到容器  id  studentService
public class StudentServiceImpl implements StudentService {

    // 去容器中查找 StudentDao 对应实例,并将当前 属性引用
    /**
     *  @Autowired 不需要 setter方法支持
     * 意义: 1.首先根据注解的类型 去容器中查找 如果只有一个,则设置
     *       2.如果按照类型查找到 多个 ,则使用 变量名( private StudentDao studentDao) 作为id 去容器中查找
     *       3.如果按照变量 名找不到,可以使用@Qualifier("studentDao2") 配置,按照传递的参数作为iD 查找
     *
     * @Resource  也是 将容器中的bean 注入到当前对象中
     * 意义:
     *      1.首先按照声明 属性名作为id 去容器中查找(private StudentDao studentDao ),
     *      2.如果没有找到 按照类型查找 ,如果查找到一个设置值 如果多个,则进入第三部
     *      3.@Resource(name = "studentDao2") 如果找到多个类型的bean 必须传入name 作为id 进行限定
     *
     * @Autowired    @Resource 的区别?
     *
     * 1. @Resource(name = "studentDao2") 等价于 @Autowired  @Qualifier
     * 2.意义
     * 3.@Resource 是jdk 注解 @Autowired spring 注解
     *
     */
//    @Autowired
//    @Qualifier("studentDao2")//如果找到多个使用  @Qualifier区分
    @Resource
    private StudentDao studentDao ;

//    public void setStudentDao(StudentDao studentDao) {
//        this.studentDao = studentDao;
//    }

    public Student findStudentById(int id) {
        return studentDao.findStudentById(id);
    }
}

//@Component// 将当前类 创建一个bean 加入到容器中 id studentDaoImpl
@Repository // 加入到容器 id studentDaoImpl
public class StudentDaoImpl implements StudentDao{
    public Student findStudentById(int id) {

        // 模拟取数据库查询
        Student student = new Student();
        student.setId(id);
        student.setName("XXXXX");

        return student;
    }
}

测试:

/**
 * 自动转配
 */
public class AnnootaionTest {


    public static void main(String[] args) {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("annotation/auto_annotation.xml");


        StudentService studentService = (StudentService) applicationContext.getBean("studentService");


        Student student =  studentService.findStudentById(12);
        System.out.println("student"+student);
    }

}

基于xml自动装配

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">



    <bean id="studentDao1" class="com.qfedu.dao.StudentDaoImpl"></bean>
    <bean id="studentDao" class="com.qfedu.dao.StudentDaoImpl"></bean>

    <!--
        加入到容器中  StudentServiceImpl

         autowire="byName" 容器中的属性 会根据属性名作为id 去容器中查找
         autowire="byType"  容器中的属性 会根据属性类型   去容器中查找
          autowire="constructor" 根据构造方法设置 属性 
    -->
    <bean id="studentService" class="com.qfedu.service.StudentServiceImpl" autowire="byName">

    </bean>

</beans>

最后

感谢大佬们能看到这里,来都来了不妨点个赞再走呗

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • Spring IOC 主要内容 Spring 框架 Spring 框架概念 ​ Spring 是众多开源java项...
    一纸油伞阅读 195评论 0 0
  • 一、启动 IOC 容器的方式 Java环境下启动 IOC 容器ClassPathXmlApplicationCon...
    Travis_Wu阅读 111评论 0 0
  • 一:Spring IOC 2种形式 注意:两种形式获取的Ioc容器是 独立的 1.xml配置文件形式:applic...
    pytho624阅读 384评论 3 0
  • Spring是什么 *Spring是一个开源框架,为了解决企业应用开发的复杂性而创建的,但现在已经不止应用于企业应...
    llccb阅读 314评论 0 0
  • 如下是整篇文章的结构,所需阅读时间大约20min Spring简介 Spring框架由Rod Johnson开发,...
    李序锴阅读 885评论 0 15