Spring框架(1)

1、IOC(控制反转)

简单的说就是,创建对象的权利,或者是控制的位置,由JAVA代码转移到spring容器,由spring的容器控制对象的创建,就是控制反转,spring创建对象时,会读取配置文件中的信息,然后使用反射给我们创建好对象之后在容器中存储起来,当我们需要某个对象时,通过id获取对象即可,不需要我们自己去new.
一句话:创建对象交给容器

2、DI(控制反转)

DI Dependency Injection,即“依赖注入” 就是创建属性时给对象属性赋值
对象功能的实现往往要依赖属性的值,那么给对象属性赋值就可以说成是依赖注入
由于对象属性不仅仅是基本数据类型,还可能是其他类,或者引用类型
那么依赖注入将会把更多的对象之间的关系整理到一起,可以行程一个庞大的依赖关系
DI处理的是对象的属性赋值和互相依赖的关系

3、IOC原理

在这里插入图片描述

4、XML实现DI

spring中的Bean的管理:
Bean(汉译咖啡豆). 又称JAVABean.其实就是JAVA程序程序中的一个个对象,所以Bean的管理其实就是spring对于JAVA程序中的对象的管理

管理的内容是什么

1 对象的创建 IOC
IOC 叫做控制反转,就是Spring给我们创建对象,然后我们直接用,不用自己NEW,
IOC处理的是对象如何创建的问题

2 属性的赋值 DI
DI处理的是对象的属性赋值和互相依赖的关系

spring给我们提供了两种关于bean的方式
1 基于XML方式的Bean管理

2 基于注解方式的Bean管理

DI给对象属性赋值
1 通过set方法给对象属性赋值

实体类

public class User {
    private Integer userid;
    private String username;
    private String password;
    重写toString
    空构造器
    有参构造器
    getter、setter方法
    }

XML配置文件

<!--
    property 就是在使用set方法实现依赖注入
    调用无参构造方法
    多个ID不能重复,不同的ID可以对应同一个对象
    User user1 = new User()
    user1.setuserid()
    -->
    <bean id="user2" class="com.wml.bean.User" lazy-init="false" scope="prototype">
        <property name="userid" value="2"></property>
        <property name="username" value="小刚"></property>
        <property name="password" value="123456"></property>
    </bean>

2 通过有参构造给对象属性赋值
XML配置文件

<!--
	调用有参构造方法
    User user3 = new User(1,"","")
    注意三个参数都要写上只写一个会报错
    constructor-arg 就是在使用构造方法实现依赖注入
    constructor-arg 的个数必须和某个构造方法的参数个数向对应
    name指的是参数名
    index指的是参数的索引
    value指的是参数值
    -->
    <bean id="user3" class="com.wml.bean.User" lazy-init="false" scope="prototype">
        <constructor-arg name="userid" value="3"></constructor-arg>
        <constructor-arg name="username" value="小明"></constructor-arg>
        <constructor-arg name="password" value="654321"></constructor-arg>
    </bean>
    <bean id="user4" class="com.wml.bean.User" lazy-init="false" scope="prototype">
        <constructor-arg index="0" value="4"></constructor-arg>
        <constructor-arg index="1" value="小黑"></constructor-arg>
        <constructor-arg index="2" value="111111"></constructor-arg>
    </bean>

3 通过p名称空间和c名称空间给对象属性赋值(实现DI)
添加约束:

       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"

配置对象:

<!--p名称空间,就是对property的简化处理-->
<bean id="user5" class="com.wml.bean.User" p:userid="5" p:username="小花" p:password="222222"></bean>
<!--c名称空间,就是对constructor-arg的简化-->
 <bean id="user6" class="com.wml.bean.User" c:userid="6" c:username="小王" c:password="333333"></bean>

4 注入空值和特殊符号
XML配置文件

<bean id="user1" class="com.wml.bean.User">
        <!--null值-->
        <property name="userid">
            <null></null>
        </property>
        <!--特殊符号 转译字符 < &lt;  >&gt;  & &amp;     -->
        <property name="username" value="&amp;xiaoming"></property>
        <!-- 特殊符号  <![CDATA[内容]]>  -->
        <property name="password">
            <value><![CDATA[&<123456>]]></value>
        </property>
    </bean>

5 关于bean引用
实体类

public class Mouse {
    private String name;
    private Date  birthdate;
    重写toString
    空构造器
    有参构造器
    getter、setter方法
    }
public class Cat {
    private String name;
    private Mouse mouse1;
    重写toString
    空构造器
    有参构造器
    getter、setter方法
    }

XML配置文件
(1)引用外部

 <!--告诉容器准备一个Date对象-->
    <bean id="date1" class="java.util.Date"></bean>
    <bean id="mouse1" class="com.wml.bean.Mouse">
        <property name="name" value="Jerry"></property>
        <!--bean引用 引用外部bean-->
        <property name="birthdate" ref="date1"></property>
    </bean>

(2)引用内部

<bean id="cat1" class="com.wml.bean.Cat">
        <property name="name" value="Tom"></property>
        <!--bean引用 引用内部bean-->
        <property name="mouse1">
            <bean class="com.wml.bean.Mouse">
                <property name="name" value="Jerry2"></property>
                <property name="birthdate">
                    <bean class="java.util.Date"></bean>
                </property>
            </bean>
        </property>
    </bean>

(3)级联引用内部

 <bean id="mouse2" class="com.wml.bean.Mouse"></bean>
    <bean id="cat3" class="com.wml.bean.Cat">
        <property name="name" value="Tom"></property>
        <!--bean引用 级联引用内部bean-->
        <property name="mouse1" ref="mouse2"></property>
        <!--用反射调用get***方法,获得对象之后,再赋值-->
        <property name="mouse1.name" value="Jerry3"></property>
        <property name="mouse1.birthdate">
            <bean class="java.util.Date"></bean>
        </property>
    </bean>

6 关于集合注入
实体类

public class Student {
    private String[] books;//有很多书集
    private Set<String> bookSet;//很多书的名字
    private List<String> booksList;
    private Map<String,String> bookMap;//书名和作者
    private List<Book> bookList1;
    重写toString
    空构造器
    有参构造器
    getter、setter方法
    }
public class Book {
    private String bname;
    private String author;
    重写toString
    空构造器
    有参构造器
    getter、setter方法
    }

XML配置文件
(1)不能公共用
添加约束:

 xmlns:p="http://www.springframework.org/schema/p"
<bean id="student1" class="com.wml.bean.Student">
       <!--数组属性注入-->
       <property name="books">
           <array>
               <value>JAVA</value>
               <value>MYSQL</value>
               <value>SPRING</value>
           </array>
       </property>
       <property name="bookSet">
           <!--Set集合注入-->
           <set>
               <value>JAVA</value>
               <value>MYSQL</value>
               <value>SPRING</value>
           </set>
       </property>
       <property name="booksList">
           <!--List集合注入-->
           <list>
               <value>JAVA</value>
               <value>MYSQL</value>
               <value>SPRING</value>
           </list>
       </property>
       <property name="bookMap">
           <!--Map集合注入-->
           <map>
               <entry key="JAVA" value="马士兵"></entry>
               <entry key="MYSQL" value="马士兵"></entry>
               <entry key="SPRING" value="马士兵"></entry>
           </map>
       </property>
       <property name="bookList1">
           <!--List对象集合注入-->
           <list>
               <ref bean="b1"></ref>
               <ref bean="b2"></ref>
               <ref bean="b3"></ref>
               <!--<bean class="com.wml.bean.Book"></bean>
               <bean class="com.wml.bean.Book"></bean>
               <bean class="com.wml.bean.Book"></bean>-->
           </list>
       </property>
   </bean>
    <!--声明多个book对象-->
    <bean id="b1" class="com.wml.bean.Book" p:bname="JAVA" p:author="马士兵"></bean>
    <bean id="b2" class="com.wml.bean.Book" p:bname="GO"   p:author="马士兵"></bean>
    <bean id="b3" class="com.wml.bean.Book" p:bname="MYBATIS" p:author="马士兵"></bean>

(2)能公共用
添加约束:

xmlns:util="http://www.springframework.org/schema/util"
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
<!--定义公共集合-->
    <util:set id="outerbookSet">
        <value>JAVA</value>
        <value>MYSQL</value>
        <value>SPRING</value>
    </util:set>
    <util:list id="outerbookList">
        <value>JAVA</value>
        <value>MYSQL</value>
        <value>SPRING</value>
    </util:list>
    <util:map id="outerbookMap">
        <entry key="JAVA" value="马士兵"></entry>
        <entry key="MYSQL" value="马士兵"></entry>
        <entry key="SPRING" value="马士兵"></entry>
    </util:map>
    <util:list id="outerbookList1">
        <!--声明多个book对象-->
        <bean id="b1" class="com.wml.bean.Book" p:bname="JAVA" p:author="马士兵"></bean>
        <bean id="b2" class="com.wml.bean.Book" p:bname="GO"   p:author="马士兵"></bean>
        <bean id="b3" class="com.wml.bean.Book" p:bname="MYBATIS" p:author="马士兵"></bean>
    </util:list>
   <bean id="student1" class="com.wml.bean.Student">
       <!--数组属性注入-->
       <property name="books">
           <array>
               <value>JAVA</value>
               <value>MYSQL</value>
               <value>SPRING</value>
           </array>
       </property>
       <property name="bookSet" ref="outerbookSet"></property>
       <property name="booksList" ref="outerbookList"></property>
       <property name="bookMap" ref="outerbookMap"></property>
       <property name="bookList1" ref="outerbookList"></property>
   </bean>
</beans>

7 工厂方式获取bean
特点 : bean标签中定义的class类不是返回的对象的类,而是生产该对象的工厂
工厂模式:GOF 设计模式
spring中给我们定义好了一个工厂接口,可以生产对象的接口,我们可以通过工厂来获取bean

定义工厂对象 实现 FactoryBean接口

public class BookFactory implements FactoryBean<Book> {
     /*public Book getBook(){
        Book book = new Book();
        book.setBname("JAVA");
        book.setAuthor("马士兵");
        return book;
    }*/
    public Book getObject() throws Exception {
        Book book = new Book();
        book.setBname("JAVA");
        book.setAuthor("马士兵");
        return book;
    }
    public Class<?> getObjectType() {
        return null;
    }
}

XML配置文件

<bean id="book" class="com.wml.bean.BookFactory"></bean>

测试代码

public class Test5 {
    @Test
    public void testSetBean(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext5.xml");
        Book book = applicationContext.getBean("book", Book.class);
        System.out.println(book);
    }
}

5、生命周期

(1)、
在这里插入图片描述
实体类

public class User1 {
    private Integer userid;
    private String username;
    private String password;
    @Override
    public String toString() {
        return "User{" +
                "userid=" + userid +
                ", username=" + username +
                ", password='" + password + '\'' +
                '}';
    }
    public User1() {
        System.out.println("第一步:User1构造");
    }
    public void setUsername(String username) {
        System.out.println("第二步:User1属性赋值");
        this.username = username;
    }
    public void initUser1(){
        System.out.println("第三步:User1初始化");
    }
    public void destoryUser1(){
        System.out.println("第五步:销毁User1");
    }
    public User1(Integer userid, String username, String password) {
        this.userid = userid;
        this.username = username;
        this.password = password;
    }
    public void setUserid(Integer userid) {
        this.userid = userid;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Integer getUserid() {
        return userid;
    }
    public String getUsername() {
        return username;
    }
    public String getPassword() {
        return password;
    }
}

XML配置文件

<bean id="book" class="com.wml.bean.BookFactory"></bean>
    <bean id="user2" class="com.wml.bean.User1" init-method="initUser1" destroy-method="destoryUser1">
        <property name="username" value="小黑"></property>
    </bean>

测试代码

public class Test6 {
    @Test
    public void testLifeCycleBean(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext6.xml");
        User1 user2 = applicationContext.getBean("user2", User1.class);
        System.out.println("第四步:User对象从容器中获取");
        System.out.println(user2);

        //关闭容器
        applicationContext.close();
    }
}

(2)、
BeanPostProcessor接口作用:
如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。
1、接口中的两个方法都要将传入的bean返回,而不能返回null,如果返回的是null那么我们通过getBean方法将得不到目标。
2、ApplicationContext会自动检测在配置文件中实现了BeanPostProcessor接口的所有bean,并把它们注册为后置处理器,然后在容器创建bean的适当时候调用它,因此部署一个后置处理器同部署其他的bean并没有什么区别。而使用BeanFactory实现的时候,bean 后置处理器必须通过代码显式地去注册,在IoC容器继承体系中的ConfigurableBeanFactory接口中定义了注册方法
在这里插入图片描述
创建后置处理器 实现 BeanPostProcesser 重写两个方法

public class MybeanProcesser implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //Object bean      实例化的bean
        //String beanName  bean的id
        System.out.println("bean:初始化方法之前");
        return bean;// 这里必须return bean
    }
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("bean:初始化方法之后");
        return bean;// 这里必须return bean
    }
}

配置后置处理器,对容器中的所有bean添加后置处理器的生命周期

<bean id="user2" class="com.wml.bean.User1" init-method="initUser1" destroy-method="destoryUser1">
        <property name="username" value="小黑"></property>
    </bean>
    <!--配置后置通知处理器-->
    <bean id="mybeanprocesser" class="com.wml.beanProcesser.MybeanProcesser"></bean>

测试代码及结果

public class Test7 {
    @Test
    public void testLifeCycleBean(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext6.xml");
        User1 user2 = applicationContext.getBean("user2", User1.class);
        System.out.println("第四步:User对象从容器中获取");
        System.out.println(user2);
        //关闭容器
        applicationContext.close();
    }
}

在这里插入图片描述

6、自动装配(自动注入)

bean自动装配
通过property标签可以手动指定给属性进行注入
我们也可以通过自动转配,完成属性的自动注入,就是自动装配,可以简化DI的配置

实体类

public class Emp {
    private Dept dept;
    public void setDept(Dept dept) {
        this.dept = dept;
    }
    @Override
    public String toString() {
        return "Emp{" +
                "dept=" + dept +
                '}';
    }
}
public class Dept {
}

XML配置文件

 <bean id="dept1" class="com.wml.bean.Dept"></bean>
    <!-- <bean id="emp" class="com.wml.bean.Emp">
        <property name="dept" ref="dept"></property>
    </bean>-->

    <bean id="emp" class="com.wml.bean.Emp" autowire="byType"></bean>
    <!--
    autowire 属性控制自动将容器中的对象注入到当前对象的属性上
    byName 根据目标id值和属性值注入,要保证当前对象的属性值和目标对象的id值一致
    byType 根据类型注入,要保证相同类型的目标对象在容器中只有一个实例
    -->

测试代码

public class Test8 {
    @Test
    public void testLifeCycleBean(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext7.xml");
        Emp emp = applicationContext.getBean("emp", Emp.class);
        System.out.println(emp);
    }
}

7、Spring_使用外部属性配置文件

spring容器可以读取.properties属性配置文件,可以将文件中的信息注入给bean
例如:引入Druid数据源,配置连接池信息
pom.xml中导入spring依赖jar
导入Druid依赖和mysql-connector依赖

<packaging>jar</packaging>
    <!--pom.xml中导入spring依赖jar-->
    <dependencies>
  <!--context上下文,容器  只需导入他就可以beans、core、spel不需要导入-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.5</version>
        </dependency>
        <!--junit单元测试测试包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>
    </dependencies>

XML配置文件

xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

 	<!--读取jdbc.properties属性配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--给链接池进行配置时要进行给链接数据库的四要素进行配置-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
       <property name="username" value="${jdbc_username}"></property>
       <property name="password" value="${jdbc_password}"></property>
       <property name="url"      value="${jdbc_url}"></property>
       <property name="driverClassName" value="${jdbc_driver}"></property>
        <!--初始化连接容量-->
       <!--<property name="initialSize" value="1"></property>-->
    </bean>

准备属性配置文件:
resources目录下准备一个jdbc.properties属性配置文件

jdbc_username=root
jdbc_password=root
jdbc_url=jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=ture&characterEncoding=UTF-8serverTimezone=UTC&allowPublicKeyRetireval=ture
jdbc_driver=com.mysql.cj.jdbc.Driver

测试代码

public class Test9 {
    @Test
    public void testdataSourceBean() throws SQLException {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext8.xml");
        DataSource dataSource = applicationContext.getBean("dataSource", DataSource.class);
        System.out.println(dataSource);
       /* Connection connection = dataSource.getConnection();*/
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值