2a Spring搭建.txt

UP 返回
1.下载
	访问 https://spring.io/projects ,选择spring framework ,下载最新版本
	本地 F:\BaiduNetdiskDownload\2019年4月黑马程序员教程\01-黑马IDEA版本Java基础+就业课程\Java开发工具\jar包\spring 提供了3.2和4.2两个版本的spring,文件夹中RELEASE-dist为spring核心包,-docs为参考文档,-dependencies为相关依赖

2.spring的核心jar包
	spring-core-3.2.2.RELEASE.jar		包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心。
	spring-beans-3.2.2.RELEASE.jar		所有应用都要用到的,它包含访问配置文件、创建和管理bean,以及进行Inversion of Control(IoC) / Dependency Injection(DI)操作相关的所有类
	spring-context-3.2.2.RELEASE.jar		Spring提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等。
	spring-expression-3.2.2.RELEASE.jar		Spring表达式语言
	com.springsource.org.apache.commons.logging-1.1.1.jar	第三方的主要用于处理日志(需要依赖,在dependencies压缩包中)

3.搭建项目
   3.1 创建项
	设置文件夹,本地是D:\EnvironmentExtends\spring,将上面必须的几个jar包复制进去(选择class文件对应的jar,不用导入源码)
	IDEA新建项目,选择Spring,点击右侧spring,在下面点击Use Library,点击create,选择刚才上面复制的路径下的几个包,确定
	后面设置一下项目名称和位置即可
   3.2 配置xml
	在src下创建beans.xml,xml文件有两种约束,.dtd和.xsd
	打开文件file:///F:/BaiduNetdiskDownload/2019%E5%B9%B44%E6%9C%88%E9%BB%91%E9%A9%AC%E7%A8%8B%E5%BA%8F%E5%91%98%E6%95%99%E7%A8%8B/01-%E9%BB%91%E9%A9%ACIDEA%E7%89%88%E6%9C%ACJava%E5%9F%BA%E7%A1%80+%E5%B0%B1%E4%B8%9A%E8%AF%BE%E7%A8%8B/Java%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/jar%E5%8C%85/spring/spring-framework-3.2.0.RC2-docs/reference/html/xsd-config.html
	复制其中的约束(这里使用的是.xsd)到xml中,再配置自己的bean,参:D:\ProjectCodes\IDEA2017\spring-test-20191006\src\beans.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">
    			  <!-- 上述的配置文件可以帮助我们在编辑xml文件时给出提示,需要联网。如果没有网络,可以事先访问该网址将文件下载到本地,再配置其位置即可 -->

   		 	<!-- bean definitions here -->
   		 	<bean id="userService" class="com.cn.service.UserServiceImpl">	<!-- spring通过反射来自动创建对象 -->
				<property name="name" value="小米"></property>		<!-- 依赖注入,会自动将值赋值给变量 -->
			</bean>
		</beans>
   3.3 使用对象
	public interface UserService {
   		 public void add();
	}

	public class UserServiceImpl implements UserService {
	
	    private String name;
	
	    @Override
	    public void add() {
	        System.out.println("创建用户:"+name);
	    }
	
	    public String getName() {
	        return name;
	    }
	
	    public void setName(String name) {
	        this.name = name;
	    }
	}

	  以前使用Service的方式,需要自己创建
        UserService usr=new UserServiceImpl();
        usr.add();

        现在使用只需从容器中获取
        //1.加载beans.xml这个spring配置文件,内部就会创建对象
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");//类路径,指的就是classes路径,打包以后src下的文件都会在这个文件夹内,故表示的路径和src同级(即路径从src之后开始写,如果放在src/com/cn/下就写/com/cn/beans.xml)
        //2.从spring容器获取对象
        UserServiceImpl usr=(UserServiceImpl) context.getBean("userService");
        //只要从容器中取出对象,取出的都是同一个,可以取出两个打印一下看看就可以了
        usr.add();

4.控制反转:IOC	Inverse of Control
   依赖注入:DI	Dependency Injection

5.Spring容器加载的方式
   5.1 ClassPathXmlApplicationContext
	ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
   5.2 通过文件系统路径获得配置文件
	ApplicationContext context=new FileSystemXmlApplicationContext("D:\ProjectCodes\IDEA2017\spring-test-20191006\src\beans.xml");	//即采用绝对路径
   5.3 使用BeanFactory
	BeanFactory factory=new XmlBeanFactory(new FileSystemResource("D:\\ProjectCodes\\IDEA2017\\spring-test-20191006\\src\\beans.xml"));	//该方法已过时
	factory.getBean()

6.BeanFactory和ApplicationContext对比
	BeanFactory采取延迟加载,第一次getBean时才会初始化Bean
	ApplicationContext采取即时加载,只要加载了ClassPathXmlApplicationContext就已经创建对象了。
	ApplicationContext是对BeanFactory的扩展,提供了更多功能:国际化处理,事件传递,Bean自动装配,各种不同应用层的Context实现

7.装配bean的三种方式(就是指在xml中写一个bean标签)
   7.1 new实现类
	<bean id="userService" class="com.cn.service.UserServiceImpl"></bean>
   7.2 通过静态工厂方法
	首先创建工厂类,静态方法返回所需的bean
	public class UserServiceFactory {
	    public static UserServiceImpl createUserService(){
	        return new UserServiceImpl();
	    }
	}
	xml中添加:
	<bean id="userService2" class="com.cn.service.UserServiceFactory" factory-method="createUserService"></bean>
	使用方法:
	UserService usr3=(UserService) context.getBean("userService2");
      usr3.add();
	会报IllegalArgumentException的异常,因为spring版本过低,3.0版本的spring需要jdk为1.7才可以。spring版本高的话就不会抛出异常了
   7.3 通过实例工厂方法
	xml中添加:
	<bean id="factory" class="com.cn.service.UserServiceFactory"></bean>
    	<bean id="userService3" factory-bean="factory" factory-method="createUserService"></bean>
	使用:
	UserService usr3=(UserService) context.getBean("userService3");

8.bean的作用域(重点前两个掌握)和生命周期
	singleton	在sprint IoC容器中仅存在一个Bean实例。此为默认值
	prototype	每次从容器中调用Bean时,都返回一个新的实例。即getBean()时相当于new Bean()
	request	每次http请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
	session	同一个HTTP Session共享一个Bean,不同Session使用不同Bean,仅适用于WebApplicationContext环境
	globalSession	一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext环境
	
	xml中的写法:
	<bean id="userService" class="com.cn.service.UserServiceImpl" scope="singleton"></bean>

	生命周期图解释(了解)
	1.instantiate bean对象实例化
	2.populate properties 封装属性
	3.如果Bean实现BeanNameAware 执行 setBeanName
	4.如果Bean实现BeanFactoryAware 执行setBeanFactory ,获取Spring容器
	5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
	6.如果Bean实现InitializingBean 执行 afterPropertiesSet 
	7.调用<bean init-method="init"> 指定初始化方法 init
	8.如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
	执行业务处理
	9.如果Bean实现 DisposableBean 执行 destroy
	10.调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy

9.给对象属性赋值的方式
   9.1 构造方法注入(下面写参数的标签要有相应的构造方法。参数不同对应不同的构造方法)
	public class Student {
	    private String name;
	    private int age;
	    private String password;
	
	    public Student(String name, int age) {
	        this.name = name;
	        this.age = age;
	    }
	}

	<bean id="stu" class="com.cn.model.Student">
        <constructor-arg name="name" value="wiw"></constructor-arg>
        <constructor-arg name="age" value="20"></constructor-arg>
      </bean>
   9.2 通过参数索引加类型给构造方法赋值(也要有对应的构造方法)
	<bean id="stu" class="com.cn.model.Student">
        <constructor-arg index="0" value="wiw" type="java.lang.String"></constructor-arg>
        <constructor-arg index="1" value="20" type="java.lang.Integer"></constructor-arg>
      </bean>
   9.3 通过属性的set方法注入(参3.2中的写法)
   9.4 通过p命名空间注入(了解)
	在xml约束里添加命名空间(p标签):xmlns:p="http://www.springframework.org/schema/p"

	<bean id="stu" class="com.cn.model.Student" p:username="wiw" p:age="15"></bean>	(报错,原因未知)
	
10 spring表达式
   10.1 value可以使用的值(<property name="name" value="小米"></property>)
	#{123}、#{'jack'} : 数字、字符串
	#{beanId}	:另一个bean引用
	#{beanId.propName}	:操作数据
	#{beanId.toString()}	:执行方法
	#{T(类).字段|方法}	:静态方法或字段

	public class Address {
    		private String addr;
	}

	public class Customer {
	    private String name;
	    private String sex="男";
	    private double pi;
	    private  Address addr;
	}

	<bean id="addr" class="com.cn.model.Address">
        <property name="addr" value="hefei"></property>		<!-- 被引用的bean -->
      </bean>

      <bean id="customer" class="com.cn.model.Customer">
        <!--<property name="name" value="#{'haha'.toUpperCase()}"></property>-->		<!-- 调用方法 -->
        <property name="name" value="#{addr.addr}"></property>							<!-- 引用别的bean的变量-->
        <property name="pi" value="#{T(java.lang.Math).PI}"></property>					<!-- 引用类中的字段-->
        <!--<property name="addr" value="#{addr}"></property>-->							<!-- 对其他bean的引用-->
        <property name="addr" ref="addr"></property>										<!-- 对其他bean的引用也可以用ref标签-->
      </bean>

11.集合注入
   集合的注入都是给<property>添加子标签
		数组:<array>
		List:<list>
		Set:<set>
		Map:<map> ,map存放k/v 键值对,使用<entry>描述
		Properties:<props>  <prop key=""></prop>  【】		
   普通数据:<value>
   引用数据:<ref>
 
	public class Programmer {
	
	    private List<String> carList;
	
	    private Map<String,String> infos;
	
	    private Properties mysqlInfos;
	}

	  <bean id="programmer" class="com.cn.model.Programmer">
	        <property name="carList">
	            <list>														<!-- 数组,Set类比该写法-->
	                <value>Audi</value>
	                <value>Menz</value>
	                <value>BWM</value>
	            </list>
	        </property>
	        <property name="infos">
	            <map>
	                <entry key="name" value="22"></entry>
	                <entry key="age" value="44"></entry>
	                <entry key="ip" value="127.0.0.1"></entry>
	            </map>
	        </property>
	        <property name="mysqlInfos">
	            <props>
	                <prop key="url">mysql:jdbc://localhost:3306/dbname</prop>
	                <prop key="user">root</prop>
	                <prop key="password">123654</prop>
	            </props>
	        </property>
	    </bean>


DOWN 返回