/**
* 程序的耦合
* 耦合:程序间的依赖关系
* 包括:
* 类之间的依赖
* 方法间的依赖
* 解耦:
* 降低程序间的依赖关系
* 实际开发中:
* 应该做到:编译期不依赖,运行时才依赖。
* 解耦的思路:
* 第一步:使用反射来创建对象,而避免使用new关键字。
* 第二步:通过读取配置文件来获取要创建的对象全限定类名
*/
-
spring 的两个重要概念:ioc,aop
-
很多对象,肯定要找个集合来存,有查找需求,这个 map 称之为容器
-
new 的方式。是主动的。有工厂为我们查找或者创建对象。是被动的。种被动接收的方式获取对象的思想就是控制反转,它是 spring 框架的核心之一。
-
明确 ioc 的作用:
削减计算机程序的耦合(解除我们代码中的依赖关系)。 -
spring5 版本是用 jdk8 编写的,所以要求我们的 jdk 版本是 8 及以上。
同时 tomcat 的版本要求 8.5 及以上。 -
了解:xml文档都有格式,为了spring的配置文件增加的节点能满足要求、合法,所以引入校验该xml的格式文件。
xmlns是xml命名空间的意思,而xmlns:xsi是指xml所遵守的标签规范。
1.xmlns:关于初始化bean的格式文件地址
2.xmlns:xsi:辅助初始化bean
3.xsi:context:关于spring上下文,包括加载资源文件
4.xsi:schemaLocation:用于声明了目标名称空间的模式文档 -
配置service,即创建对象放在容器中,
在xml的配置为(使用xml配置需要在接口的实现类中若有属性,则需有有set方法,注解则不需要。所以在配置时,推荐使用注解,注意注解就需要开启扫描)<bean id="accountService" class="com.test.service.impl.AccountServiceImpl">
使用注解: 有接口,还要有实现类,在实现类上加注解
@Service("accountService") public class AccountService implements IAccountService { }
-
实例尝鲜
准备 spring 的开发包 创建业务层接口和实现类 /** * 账户的业务层接口 */ public interface IAccountService { /** * 保存账户(此处只是模拟,并不是真的要保存) */ void saveAccount(); } /** * 账户的业务层实现类 */ public class AccountServiceImpl implements IAccountService { private IAccountDao accountDao = new AccountDaoImpl();//此处的依赖关系有待解决 @Override public void saveAccount() { accountDao.saveAccount(); } } 创建持久层接口和实现类 /** * 账户的持久层接口 */ public interface IAccountDao { /** * 保存账户 */ void saveAccount(); } /** * 账户的持久层实现类 */ public class AccountDaoImpl implements IAccountDao { @Override public void saveAccount() { System.out.println("保存了账户"); } } 基于 XML 的配置 第一步:拷贝必备的 jar 包到工程,或者maven坐标 第二步:resources下创建applicationContext.xml 给配置文件导入约束: /spring-framework-5.0.2.RELEASE/docs/spring-framework-reference/html5/core.html <?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> 第三步:让 spring 管理资源,在配置文件中配置 service 和 dao <!-- bean 标签:用于配置让 spring 创建对象,并且存入 ioc 容器之中 id 属性:对象的唯一标识。 class 属性:指定要创建对象的全限定类名 --> <!-- 配置 service --> <bean id="accountService" class="com.test.service.impl.AccountServiceImpl"></bean> <!-- 配置 dao --> <bean id="accountDao" class="com.test.dao.impl.AccountDaoImpl"></bean> 最后测试配置是否成功
-
测试时,使用时:
@Test public void testSpring(){ //1.使用 ApplicationContext 接口,就是在获取 spring 容器 ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); //2.根据 bean 的 id 获取对象 IAccountService accountService = (IAccountService)ac.getBean("accountService"); accountService.findAll(); }
-
ClassPathXmlApplicationContext:
它是从类的根路径下加载配置文件
AnnotationConfigApplicationContext:
当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。 -
spring中工厂类的结构图
-
容器中的对象要注意,有单例类,和多例类之分
单例对象:scope=“singleton”
一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期:
对象出生:当应用加载,创建容器时,对象就被创建了。
对象活着:只要容器在,对象一直活着。
对象死亡:当应用卸载,销毁容器时,对象就被销毁了。多例对象:scope=“prototype”
每次访问对象时,都会重新创建对象实例。
生命周期:
对象出生:当使用对象时,创建新的对象实例。
对象活着:只要对象在使用中,就一直活着。
对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。 -
在放入容器中的对象若有属性,需要注入有三总方式
1,构造函数注入在实例类中: public class AccountServiceImpl implements IAccountService { private String name; private Integer age; private Date birthday; public AccountServiceImpl(String name, Integer age, Date birthday) { this.name = name; this.age = age; this.birthday = birthday; } } 在xml配置文件中: <bean id="accountService" class="com.test.service.impl.AccountServiceImpl"> <constructor-arg name="name" value=" 张三 "></constructor-arg> <constructor-arg name="age" value="18"></constructor-arg> <constructor-arg name="birthday" ref="now"></constructor-arg> </bean>
2,使用set方法注入
把上面的实例类中的构造方法换成这三个, public void setName(String name) { this.name = name; } public void setAge(Integer age) { this.age = age; } public void setBirthday(Date birthday) { this.birthday = birthday; } 在xml配置文件中: <bean id="accountService" class="com.test.service.impl.AccountServiceImpl"> <property name="name" value="test"></property> <property name="age" value="21"></property> <property name="birthday" ref="now"></property> </bean>
3,使用 p 名称空间注入数据(本质还是调用 set 方法)
-
若成员为集合则:
public class AccountServiceImpl implements IAccountService { private String[] myStrs; private List<String> myList; private Set<String> mySet; private Map<String,String> myMap; private Properties myProps; public void setMyStrs(String[] myStrs) { this.myStrs = myStrs; } public void setMyList(List<String> myList) { this.myList = myList; } public void setMySet(Set<String> mySet) { this.mySet = mySet; } public void setMyMap(Map<String, String> myMap) { this.myMap = myMap; } public void setMyProps(Properties myProps) { this.myProps = myProps; } List 结构的: array,list,set Map 结构的 map,entry,props,prop <bean id="accountService" class="com.test.service.impl.AccountServiceImpl"> <!-- 在注入集合数据时,只要结构相同,标签可以互换 --> <!-- 给数组注入数据 --> <property name="myStrs"> <set> <value>AAA</value> <value>BBB</value> <value>CCC</value> </set> </property> <!-- 注入 list 集合数据 --> <property name="myList"> <array> <value>AAA</value> <value>BBB</value> <value>CCC</value> </array> </property> <!-- 注入 set 集合数据 --> <property name="mySet"> <list> <value>AAA</value> <value>BBB</value> <value>CCC</value> </list> </property> <!-- 注入 Map 数据 --> <property name="myMap"> <props> <prop key="testA">aaa</prop> <prop key="testB">bbb</prop> </props> </property> <!-- 注入 properties 数据 --> <property name="myProps"> <map> <entry key="testA" value="aaa"></entry> <entry key="testB"> <value>bbb</value> </entry> </map> </property> </bean>
-
@Component, @Controller,@Service,@Repository他们四个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。
,只不过是提供了更加明确的语义化。
@Controller:一般用于表现层的注解。
@Service:一般用于业务层的注解。
@Repository:一般用于持久层的注解。
细节:如果注解中有且只有一个属性要赋值时,且名称是 value,value 在赋值是可以不写。 -
2.3.2 用于注入数据的注解:
-
相当于:
<bean id="" class="" scope="">
@Autowired
作用:
自动按照类型注入。当使用注解注入属性时,set 方法可以省略。它只能注入其他 bean 类型。当有多个
类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到
就报错。
@Qualifier
作用:
在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和@Autowire 一起使用;但是给方法参数注入时,可以独立使用。
属性:
value:指定 bean 的 id。
@Resource
作用:
直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。
属性:
name:指定 bean 的 id。
@Value
作用:
注入基本数据类型和 String 类型数据的
属性:
value:用于指定值 -
用于改变作用范围的:
相当于:<bean id="" class="" scope="">
@Scope
作用:
指定 bean 的作用范围。
属性:
value:指定范围的值。
取值:singleton
prototype request session globalsession