目录
3.2、写配置文件applicationContext.xml
6.4.3、其余的request、session、application这些只能在web开发中使用到
1、Spring
1.1、简介
官方参考文件:Core Technologies
1.2、优点
-
Spring是一个开源的免费框架(容器)
-
Spring是一个轻量级的、非入侵式的框架
-
控制反转(IOC),面向切面编程(AOP)√
-
支持事务的处理,对框架整合的支持
总结:Spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架
1.3、组成
七大模块:
1.4、拓展
-
Spring Boot
-
一个快速开发的脚手架
-
基于SpringBoot可以快速的开发单个微服务
-
预定大于配置!
-
-
Spring Cloud
-
Spring Cloud是基于SpringBoot实现的
-
学习SringBoot的前提要完全掌握Spring及SpringMVC!!
2、IOC理论推导
2.1、UserDao接口
package dao;
public interface TestDao {
public void sayHello();
}
2.2、UserDaoImpl实现类
public class TestDaoImpl implements TestDao {
@Override
public void sayHello() {
System.out.println("Hello Spring Welcome");
}
}
2.3、UserService业务接口
public interface TestService {
void say();
}
2.4、UserServiceImpl业务实现类
public class TestServiceImpl implements TestService {
private TestDao testDao;
//通过setTestDao将控制权转移给用户
public void setTestDao(TestDao testDao){
this.testDao = testDao;
}
public void say() {
testDao.say();
}
}
在写业务之前,用户不同的需求可能会影响原来的代码,需要根据用户需求更改源代码,如果数据过多,就惨了。
使用set接口实现:
public void setTestDao(TestDao testDao){
this.testDao = testDao;
}
-
之前,程序时主动创建对象,控制权在程序员手上,
-
使用set注入后,程序不在具有主动性,而是变成了被动的接收对象
减少了程序的耦合性。
3、HelloSpring例子
3.1、注入依赖(导包)
<!--Spring核心基础依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--日志相关-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
3.2、写配置文件applicationContext.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">
</beans>
3.3、接口
public interface TestDao {
public void say();
}
3.4、实现类
public class TestDaoImpl implements TestDao {
@Override
public void say() {
System.out.println("Hello Spring first");
}
}
public class TestDaoImpl02 implements TestDao{
@Override
public void say() {
System.out.println("Welcome to second");
}
}
3.5、将控制权交于Spring
<?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">
<!--把testDao对象的创建权交给Spring,放入容器中-->
<!--使用Spring创建对象,在Spring这些都称为bean-->
<bean id="testDao1" class="wen.dao.TestDaoImpl"></bean>
<bean id="testDao2" class="wen.dao.TestDaoImpl02"></bean>
<!--按照用户需求只需修改class中的TestServiceImpl即可-->
<!--需要调用从容器中取就行了-->
<bean id="TestServiceImpl" class="wen.service.TestServiceImpl">
<property name="testDao" ref="testDao2"></property>
</bean>
</beans>
3.6、测试
// TestService test = new TestServiceImpl();
// ((TestServiceImpl) test).setTestDao(new TestDaoImpl());
// test.say();
//测试类里只需要找到配置文件,然后通过getBean方法来获得所需要的东西
//获取applicationContext:拿到Spring容器
ApplicationContext Context = new ClassPathXmlApplicationContext("applicationContext.xml");
//拿到容器,需要什么,就直接get什么
TestServiceImpl testServiceImpl = (TestServiceImpl) Context.getBean("TestServiceImpl");
//调用方法
testServiceImpl.say();
}
3.7、项目结构:
控制反转:
-
控制
-
谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象由Spring来创建。
-
-
反转
-
程序本身不创建对象,而变成被动的接收对象
-
-
依赖注入
-
利用set方法来进行注入
-
IOC是一种编程思想,由主动的编程变成被动的接收
可以通过newClassPathXmlApplicationContext去浏览源码
使用Spring后,就可以不再去程序中更改代码,要实现不同的操作,只需要在xml配置文件中进行修改,所谓IOC,就是由Spring来创建,管理,装配。
4、IOC创建对象的方式
4.1、无参构造创建对象,(默认实现!)
public class User {
private String name;
public void User(){
System.out.println("这是一个无参构造!!!");
}
//有参构造
// public User(String name){
// this.name = name;
// }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+name);
}
<bean id="user" class="wen.pojo.User">
<!--注入属性-->
<property name="name" value="天赐"></property>
</bean>
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User name = (User) context.getBean("user");
name.show();
}
4.2、使用有参构造创建对象
-
下标赋值
<!--第一种,下标赋值-->
<bean id="user" class="wen.pojo.User">
<constructor-arg index="0" value="天赐"></constructor-arg>
</bean>
-
类型
<!--第二种,通过类型,不建议使用,有两个相同类型的参数就不行了-->
<bean id="user" class="wen.pojo.User">
<constructor-arg type="java.lang.String" value="tainci"></constructor-arg>
</bean>
-
参数名
<!--第三种,直接通过参数名来设置-->
<bean id="user" class="wen.pojo.User">
<constructor-arg name="name" value="天赐"></constructor-arg>
</bean>
5、Spring配置
5.1、别名
<!-- 别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
<alias name="user" alias="bieming"></alias>
5.2、Bean的配置
<!--
id:bean 的唯一标识符,也就是对象名
class : bean 对象所对应的全限定名 :包名+类型
name: 也是别名,而且name可以同时取多个别名
-->
<bean id="user1" class="wen.pojo.User" name="user2,u2">
<constructor-arg value="张三"/>
</bean>
5.3、import
一般用于团队开发使用,可以将多个配置文件导入合并为一个
假设,先要将项目中多个人开发,这三个人复制不同的类开发,不同的类需要注册不同的bean,我们可以利用import将所有人的配置文件合并为一个总的,放在总的配置文件中:applicationContext.xml
-
FirstDemo.xml
-
ScendDemo.xml
-
ThirdDemo.xml
-
applicationContext.xml
<import resource="beans1.xml"></import> <import resource="beans2.xml"></import> <import resource="beans3.xml"></import>
使用的时候直接配置即可
6、依赖注入(DI)
6.1、构造器注入
前面说过
6.2、Set注入【重点】
-
依赖注入:Set注入!
-
依赖:bean对象的创建依赖于容器
-
注入:bean对象中的所有属性由容器来注入
-
【环境搭建】
6.2.1、复杂类型
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Map<String,String> card;
private Set<String> game;
private Properties info;
private String wife;
getter setter.....
}
6.2.2、真实测试
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.toString());
}
6.2.3、Spring配置
<bean id="address" class="wen.pojo.Address">
<property name="address" value="四川"/>
</bean>
<bean id="student" class="wen.pojo.Student">
<!--第一种,普通值注入value-->
<property name="name" value="天赐"/>
<!--第二种,Bean注入,ref-->
<property name="address" ref="address"/>
<!--第三种,Array-->
<property name="books">
<array>
<value>书01</value>
<value>书02</value>
<value>书03</value>
</array>
</property>
<!--第四种,List-->
<property name="hobbies">
<list>
<value>敲代码</value>
<value>玩游戏</value>
<value>看电影</value>
</list>
</property>
<!--第五种,Map-->
<property name="card">
<map>
<entry key="身份证" value="510123146521346"/>
<entry key="银行卡" value="5321661316546513"/>
</map>
</property>
<!--第六种,Set-->
<property name="game">
<set>
<value>LOL</value>
<value>COC</value>
<value>BOB</value>
</set>
</property>
<!--第七种,Null-->
<property name="wife">
<null/>
</property>
<!--第八种,Properties-->
<property name="info">
<props>
<prop key="driver">2312314</prop>
<prop key="url">10.10.94.65</prop>
<prop key="card">64343437437</prop>
<prop key="hobbies">game</prop>
</props>
</property>
</bean>
6.2.4、输出
Student{name='天赐', address=Address{address='四川'}, books=[书01, 书02, 书03], hobbies=[敲代码, 玩游戏, 看电影], card={身份证=510123146521346, 银行卡=5321661316546513}, game=[LOL, COC, BOB], info={hobbies=game, url=10.10.94.65, card=64343437437, driver=2312314}, wife='null'}
6.3、拓展方式注入
6.3.1、p命名空间注入和c命名空间注入
1.加入约束
首先要在配置文件内加入xml约束:xmlns:p="http://www.springframework.org/schema/p";xmlns:c="http://www.springframework.org/schema/c"
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--p命名空间注入,可以直接注入属性的值:property-->
<bean id="user" class="wen.pojo.User" p:name="天赐" p:age="21"/>
<!--c命名空间注入,通过构造器注入:construct-agrs-->
<bean id="user2" class="wen.pojo.User" c:name="小文" c:age="20"/>
</beans>
2.测试:
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//通过反射,User.class,不用再强转
//User user = context.getBean("user", User.class);
User user = context.getBean("user2", User.class);
System.out.println(user);
}
3.官方解释:
6.4、Bean的作用域
6.4.1、单例模式(Spring默认单例)
<!--单例模式:singleton(Spring默认机制)-->
<bean id="user1" class="wen.pojo.User" p:name="天赐" p:age="21" scope="singleton"/>
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//通过反射,User.class,不用再强转
User user01 = context.getBean("user1", User.class);
User user02 = context.getBean("user1", User.class);
System.out.println(user01.hashCode()); //825658265
System.out.println(user02.hashCode()); //825658265
System.out.println(user01 == user02); //true
}
6.4.2、原型模式
每次从容器中get的时候,都会产生一个新对象
<!--原型模式(prototype):每次从容器中get的时候,都会产生一个新对象-->
<bean id="user2" class="wen.pojo.User" c:name="小文" c:age="20" scope="prototype"/>
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//通过反射,User.class,不用再强转
User user01 = context.getBean("user2", User.class);
User user02 = context.getBean("user2", User.class);
System.out.println(user01.hashCode()); //787738361
System.out.println(user02.hashCode()); //607932305
System.out.println(user01 == user02); //false
}