Spring第一天笔记

一、spring的介绍

  1. spring 开源的轻量级框架
  2. spring的两大核心:IOC ,AOP
  3. IOC(Inverse Of Control:反转控制)
  4. AOP(Aspect Oriented Programming:面向切面编程)

二、spring和EJB的区别(了解)

EJB可以说像是一个Web Service,但也不完全是,比如EJB将编写好的业务组件放置在EJB容器上,然后提供接口给客户端访问;但是功能不仅限如此,EJB标准中提供了很多规范等,而这些规范只有在EJB容器才能正常运行。
EJB重量级框架

Spring容器取代了原有的EJB容器,因此以Spring框架为核心的应用无须EJB容器支持,可以在Web容器中运行。
Spring容器管理的不再是复杂的EJB组件,而是POJO(Plain Old Java Object) Bean。
Spring轻量级框架

三、耦合和解耦

  1. 什么是耦合
    模块之间的关联程度, 依赖程度
  2. 什么是解耦
    降低模块之间的耦合度(依赖关系)
  3. 解耦的目的
    编译器不依赖,运行期才依赖
  4. 解耦思路
    (1) 把全限类名都放到配置文件中
    (2) 通过工厂帮助创建对象

四、解耦代码(了解)

        try {	//耦合度高,在编译时就需要其他模块支持(new 对象)
            Driver driver = new Driver();
            //注册驱动
            DriverManager.registerDriver(driver);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        try {	//解耦思想,通过全限类名反射创建对象
            Class.forName("com.mysql.jdbc.Driver");
//此时的好处是我们的类中不再依赖具体的驱动类,此时就算删除 mysql的驱动jar包依然可以编译
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

同时,也产生了一个新的问题,mysql 驱动的全限定类名字符串是在 java 类中写死的,一旦要改还是要修改源码。
解决这个问题也很简单,使用配置文件配置。

五、控制反转-- 自定义IOC(了解)

  1. 引入依赖
		<dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.1.6</version>
        </dependency>
  1. 配置文件 beans.xml
<beans>
    <!--
        用bean标签配置所有的bean对象
        id: 对象的唯一的标志
        class:类名
    -->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"></bean>
</beans>
  1. 创建BeanFactory工厂对象
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 创建bean对象的工厂类
 */
public class BeanFactory {
    private static Map<String ,Object> map = new HashMap<>();
    //提前把所有的对象创建出来,存储
    //Map  :因为有查找需求 --相当于容器对象-- 包含了所有的对象
    //静态代码块
    static{
        //获取配置文件的输入流对象
        InputStream inputStream = BeanFactory.class.getResourceAsStream("/beans.xml");
        //解析xml获取xml中所有的信息
        SAXReader reader = new SAXReader();
        try {
            //创建文档对象
            Document doc = reader.read(inputStream);
            //获取根节点
            Element root = doc.getRootElement();
            //获取根节点中所有的子节点
                //element("bean") : 获取第一个叫bean的子节点
                //elements("bean") : 获取所有叫bean的子节点
                //elements() : 获取所有的子节点
            List<Element> beanList = root.elements("bean");
            //获取每一个bean的id和class
            for (Element element : beanList) {
                String id = element.attributeValue("id");
                String className = element.attributeValue("class");

                //通过className全限类名创建对象--获取字节码
                Class clazz = Class.forName(className);
                //通过反射创建对象
                Object obj = clazz.newInstance();
                //存储在Map集合中
                    //key: id
                    //value:obj
                map.put(id ,obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //需要实现的功能,传入一个名字,获取一个Bean对象
    public static Object getBean(String name){

        return map.get(name);
    }
}

  1. 测试
 public static void main(String[] args) {
        Object userService1 = BeanFactory.getBean("userService");
		System.out.println(userService1);		//@448139f0
		
		Object userService2 = BeanFactory.getBean("userService");
		System.out.println(userService2);		//@448139f0
    }

六、spring的IOC入门(掌握)

  1. 引入依赖
  <!--引入spring 的最核心依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
  1. 创建beans.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!--
http://www.springframework.org/schema/beans: 引入bean的名称空间
约束:现在xml的书写
    dtd:mybatis
    schema:spring

http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd :引入约束
-->
<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="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
</beans>

  1. 创建容器对象,根据id获取对象
 //创建spring的IOC容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        //获取对象
        Object userDao = ac.getBean("userDao");
        System.out.println(userDao);

七、IOC的细节

1、容器对象的类结构图
  1. beanFactory 是spring容器的顶层接口

  2. 接口ApplicationContext是 beanFactory子接口

    实现类:
    ClassPathXmlApplicationContext  -- 从类路径之下读取配置文件 (常用)
    FileSystemXmlApplicationContext -- 从绝对路径指定的配置文件读取
    AnnotationConfigApplicationContext -- 纯注解配置使用的类 (常用)
    
  3. BeanFactory与ApplicationContext区别

		Resource resource = new ClassPathResource("beans.xml");
//      BeanFactory:创建容器对象时,只是加载了配置文件,没有创建对象
//      获取对象时:创建对象
        BeanFactory beanFactory = new XmlBeanFactory(resource);
        Object userDao = beanFactory.getBean("userDao");
        System.out.println(userDao);

        //创建spring的IOC容器
        //在创建容器对象时,创建对象  (常用)
        //ApplicationContext:在创建容器时只创建单例模式的对象
        //						       多例模式的对象,在获取时创建
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        Object userDao2 = ac.getBean("userDao");
        System.out.println(userDao2);
2、getBean方法(掌握)
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //根据名称获取该对象
        Object userDao = ac.getBean("userDao");
        System.out.println(userDao);
//        根据类型获取该对象
//        如果该类型有两个实现类,会执行异常
        UserDao userDao = ac.getBean(UserDao.class);
        System.out.println(userDao);
//        得到是id为userDao1的对象,类型为UserDao接口的实现类
        UserDao userDao = ac.getBean("userDao2", UserDao.class);
        System.out.println(userDao);
3、bean对象的范围和生命周期(掌握)
springIOC容器默认的单例模式:  单例模式的对象在创建容器时创建,销毁容器时销毁
scope:	prototype	原型模式(多例模式):获取时创建,当对象长时间不在被引用,则被垃圾回收机制回收
scope:	singleton 	单例模式
scope:	request  	请求范围
scope:  session 	会话范围
scope:  global session :全局范围 -- spring 5的新特性中被删除了

init-method:指定类中的初始化方法名称。
destroy-method:指定类中销毁方法名称。
4、实例化bean的三种方法(了解)
1 .<bean id="name" class="全限类名">
		getBean(name)
2. 根据静态工厂获取对象

public class StaticFactory {
    public static UserDao getUserDao(){
        return new UserDaoImpl();
    }
}
<!--通过静态工厂创建UserDao对象-->
    <!--
        factory-method: 工厂方法,返回UserDao对象的方法名
    -->
    <bean id="userDao" class="com.itheima.factory.StaticFactory" 
    factory-method="getUserDao"></bean>

3. 根据实例(非静态)工厂获取对象
public class InstanceFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}
 <!--创建实例工厂对象-->
 <bean id="instanceFatory" class="com.itheima.factory.InstanceFactory"></bean>
 <!--通过实例工厂创建UserDao对象-->
 <bean id="userDao2" factory-bean="instanceFatory" 
 factory-method="getUserDao"></bean>

5、依赖注入(掌握)
a.什么是依赖注入
	虽然我们所需的对象交给工厂创建,但是有些对象与对象之间存在依赖关系
	(例如UserService里面需要UserDao支持)
	业务层需要持久层的对象,在配置文件中给业务层传入持久层的对象,就是依赖注入
b. ioc
	控制反转包含了依赖注入和依赖查找
6、构造方法注入(掌握)
<!--依赖注入-->
		value 属性只能赋值简单的类型:基本数据类型和String类型
        ref:  pojo类型,复杂类型, 关联创建好的对象
    <!--默认创建对象方式,使用默认的空的构造方法创建对象-->
    <bean id="user" class="com.itheima.domain.User">
        <!--通过构造方法参数的索引赋值-->
        <constructor-arg index="0" value="1"></constructor-arg>
   		<constructor-arg index="1" value="张三"></constructor-arg>
   		 <!--通过构造方法参数类型赋值-->
    	<constructor-arg type="java.lang.Integer" value="2"></constructor-arg>
   		<constructor-arg type="java.lang.String" value="李四"></constructor-arg>
        <!--通过构造方法参数名字赋值-->
        <constructor-arg name="id" value="3"></constructor-arg>
        <constructor-arg name="username" value="王五"></constructor-arg>
   		<constructor-arg name="sex" value=""></constructor-arg>
        <constructor-arg name="birthday" ref="birthday"></constructor-arg>
    </bean>

	<bean id="birthday" class="java.util.Date"></bean>
7、set方法注入属性(常用)(掌握)
<!--通过set方法注入-->
    <bean id="user2" class="com.itheima.domain.User">
        <!--property :属性注入 , 先找到set方法,才能最终找到属性-->
        <property name="username" value="王朝"></property>
        <property name="birthday" ref="birthday"></property>
        <property name="sex" value=""></property>
        <property name="id" value="4"></property>
    </bean>
8、p名称空间注入:基于set方法注入— 了解
a、在头部文件中引入p名称空间
	xmlns:p="http://www.springframework.org/schema/p"
b、使用p名称空间注入属性
    <bean id="user3" class="com.itheima.domain.User"
        p:id="5" p:username="马汉" p:sex="" p:birthday-ref="birthday"
        ></bean>
9、注入集合属性(掌握)

给类中的集合成员传值,它用的也是set方法注入的方式

<!--注入集合属性-->
    <bean id="user4" class="com.itheima.domain.User">
        <!--array ,list ,set 结构相同,标签可以混用-->
        <property name="list">
            <set>
                <value>javaSE</value>
                <value>javaEE</value>
                <value>javaME</value>
            </set>
        </property>

        <property name="set">
            <array>
                <value>javaSE</value>
                <value>javaEE</value>
                <value>javaME</value>
            </array>
        </property>
        
        <property name="strs">
            <list>
                <value>javaSE</value>
                <value>javaEE</value>
                <value>javaME</value>
            </list>
        </property>
        
        <!--map集合properties结构相同,可以通用-->
        <property name="map">
           <props>
            <prop key="" >five</prop>
            <prop key="" >six</prop>
            <prop key="" >seven</prop>
        </props>
        </property>

        <property name="properties">
            <map>
                <!--键值对配置-->
                <entry key="" value="one"></entry>
                <entry key="" value="two"></entry>
                <entry key="" value="three"></entry>
                <entry key="" value="four"></entry>
            </map>
        </property>
    </bean>  
发布了33 篇原创文章 · 获赞 2 · 访问量 980

猜你喜欢

转载自blog.csdn.net/Rhin0cer0s/article/details/98329646