- 一、spring文件及注解
- 三、引入其他配置文件(分模块开发)
- 四、Spring的重点配置
- 五、SpringAPI
- 六、配置数据源
- 七、Spring配置数据源:DataSource——.set方法注入
- 八、Spring单独配置数据源:xml加载properties文件——分开数据库与Spring
-
九、Spring注解开发
-
1、 Spring原始注解
- @Component——id——实例化——随便那个——无语义
- @Controller——Web层控制类实例化——语义化
- @Service——Service层服务类实例化——语义化
- @Repository——id——Dao层数据存储类实例化——语义化
- @Autowired——无需Setter——字段按类型注入——可单独使用
- @Qualifier——name/id——@Autowired+按名称注入——必须配合使用
- @Resource——按名称注入=@Autowired+@Qualifier——J2EE提供
- @Value——注入普通属性
- @Scope——Bean作用范围
- @PostConstruct——Bean初始化方法——构造后
- @PreDestroy——Bean销毁方法——销毁前
- @Order——注入对象引用集合
- 2、组件扫描:component-scan
- 3、2种配置/注解方式对比:
- 2、Spring新注解
- 3、Spring对象创建——实例化——找到类创建对象——所在位置
- 4、Spring注入
-
1、 Spring原始注解
1、spring配置主要全部文件
pom.xml
<dependencies>
<!--————————————————添加Spring依赖支持————————————————-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.7</version>
</dependency>
<!--————————————————添加Spring测试支持————————————————-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.7</version>
</dependency>
<!--————————————————添加Spring-MVC视图表现层支持————————————————-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.7</version>
</dependency>
<!--————————————————添加Spring 数据库事务管理支持————————————————-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.7</version>
</dependency>
<!--————————————————添加Spring-aop面向切面编程支持————————————————-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.7</version>
</dependency>
</dependencies>
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<bean id="userDao" class="com.remli.dao.impl.UserDaoImpl"></bean>
</beans>
Main.java
public static void main(String[] args) {
/*解析application.xml配置文件获取Bean实例(对象)*/
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
/*对象获取并强制转换类型*/
UserDao userDao = (UserDao) app.getBean("userDao");
/*对象调用方法*/
userDao.save();
}
/*获取文件流*/
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
/*接口*/ /*接口实现*/
/*获取对象*/ /*强转对象*/
UserService userService = (UserService) app.getBean("userService");
userService.save();
UserDao.java
public interface UserDao {
/*接口的方法*/
public void save();
}
UserDaoImpl.java
public class UserDaoImpl implements UserDao {
/*实现接口的类的方法*/
public void save() {
System.out.println("程序启动");
}
}
2、spring配置主要全部注解
3、Spring重点基础知识
1.名词解释
-
类(人类):共同特征的实体的集合、模板、一类事物、抽象、概念、同种属性
实例:一个真实的对象
对象(个人):组成类的元素、类的具体实现、实际执行者
属性:数据(变量/值)
定义:编译器创建对象、分配内存、取名(变量名/对象名)
声明:声明对象(对象名/对象类型)、告知编译器对象/属性的情况
实例化:类创建对象的过程
初始化:为变量分配内存空间、并确定其初始值的过程
构造方法:与类同名的特殊方法、创建对象
构造器:与类同名的特殊方法、创建对象
2.Bean生命周期:1实例化、2属性赋值、3初始化、4使用、5销毁
-
实例化前阶段:执行Instantiation Aware Bean PostProcessor Adapter的post Process Before ln station方法
执行Instantiation Aware Bean PostProcessor Adapter的determine Candidate Constructors方法
接口Merged Bean Definition PostProcessor的post Process Merged Bean Definition方法
实例化Bean(执行Bean构造方法)
实例化后阶段:执行Instantiation Aware Bean PostProcessor Adapter的post Process After In station方法。方法返回false的时候, 后续的Bean属性赋值前处理、Bean属性赋值都会被跳过了,
属性赋值前阶段(可在此修改属性的值):执行Instantiation Aware Bean PostProcessor的post Process Properties方法。返回空的时候, 表示这个bean不需要设置属性, 直接返回了, 直接进入下一个阶段。
属性赋值(Populate)
Aware接口
执行Instantiation Aware Bean PostProcessor Adapte的post Process Before ln it i alization方法
自定义初始化方法
执行Instantiation Aware Bean PostProcessor Adapte的post Process After ln it i alization方法
容器创建成功,提供使用
调用自定义销毁方法方法
3.Bean 标签属性
-
id 属性:唯一性、不可重复
属性值任意命名,但不可以包含中文以及特殊字符。
根据 id 属性值得到配置对象。 -
class 属性:类的全路径名称
创建对象所在类的全路径名称。 -
name 属性:不可重复
功能和 id 一致。已基本不用。
区别: id 属性值不可以包含特殊字符, name 属性值可以包含。 -
scope 属性
bean 作用范围属性值:
取值范围 | |
---|---|
singleton 单例 | 默认值、只生成1个实例 |
prototype 多例 | 多例的 |
request | WEB项目中, Spring创建一个Bean的对象, 将对象存入到request域中 |
session | WEB项目中, Spring创建一个Bean的对象, 将对象存入到session域中 |
global session | WEB项目中, 应用在Portlet环境, 如果没有Portlet环境那么global Session相当于session |
-
作用域:scope
singleton: 单例模式,在整个Spring IoC容器中,singleton作用域的Bean将只生成一个实例。 prototype: 每次通过容器的getBean()方法获取prototype作用域的Bean时,都将产生一个新的Bean实例。 request: 对于一次HTTP请求,request作用域的Bean将只生成一个实例,这意味着,在同一次HTTP请求内,程序每次请求该Bean,得到的总是同一个实例。只有在Web应用中使用Spring时,该作用域才真正有效。 session:该作用域将 bean 的定义限制为 HTTP 会话。 只在web-aware Spring ApplicationContext的上下文中有效。 global session: 每个全局的HTTP Session对应一个Bean实例。在典型的情况下,仅在使用portlet context的时候有效,同样只在Web应用中有效。
4.Spring核心:
-
Spring容器接口:ApplicationContext
ClassPathXmlApplicationContext: 从类加载路径下搜索配置文件,并根据配置文件来创建Spring容器。 FileSystemXmlApplicationContext: 从文件系统的相对路径或绝对路径下去搜索配置文件,并根据配置文件来创建Spring容器。
4、bean实例化:无参、工厂静态、工厂实例
1.无参构造方法实例化:默认
<!--找无参构造方法-->
<bean id="userDao" class="com.remli.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy" scope="prototype"></bean>
/*重写无参构造——修改默认构造方法——对应接口*/
public UserDaoImpl(){
System.out.println("无参构造修改:UserDaoImpl对象创建...");
}
2.工厂静态方法实例化:直接调用方法
<!--找全包名对应内部指定的方法、去返回对应的对象-->
<bean id="userDao1" class="com.remli.factory.StaticFactory" scope="prototype" factory-method="getUserDao"></bean>
public class StaticFactory {
/*对象工厂——对象创建——返回对象*/
public static UserDao getUserDao() {
/*返回对象*/
return new UserDaoImpl();
}
}
3.工厂实例方法实例化:先有工厂对象再调方法
<!--先创建工厂对象-->
<bean id="factory" class="com.remli.factory.DynamicFactory" scope="prototype" ></bean>
<!--从容器当中工厂对象内部的方法获取指定返回的对象-->
<bean id="userDao2" factory-bean="factory" factory-method="getUserDao"></bean>
public class DynamicFactory {
/*对象工厂*/
public UserDao getUserDao() {
/*返回对象*/
return new UserDaoImpl();
}
}
5、依赖注入DI:注入类型:对象、普通数据、集合数据
1.构造方法注入:有参构造
<bean id="userService" class="com.remli.service.impl.UserServiceImpl">
<!--参数名--> <!---->
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
public UserServiceImpl(UserDao userDao) {/*有参构造*/
this.userDao = userDao;
}
2.set方法注入:
<!--找无参构造方法-->
<bean id="userDao" class="com.remli.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy" scope="prototype"></bean>
<!--set依赖注入-->
<bean id="userService" class="com.remli.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void save() {
userDao.save();
}
3.p命名空间注入:(本质set)
1引入p命名空间:
xmlns:p="http://www.springframework.org/schema/p"
2修改注入方式:
<bean id="userService" class="com.remli.service.impl.UserServiceImpl" p:userDao-ref="userDao" />
6、依赖注入类型:引用数据(对象)、普通数据、集合数据
1.普通数据
private String username;
private int age;
public void setUsername(String username) {
this.username = username;
}
public void setAge(int age) {
this.age = age;
}
<bean id="userDao11" class="com.remli.dao.impl.UserDaoImpl" >
<!--属性注入-->
<property name="username" value="注意空格"/>
<property name="age" value="2021825"/>
</bean>
/*获取文件流*/
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
/*接口*/ /*接口实现*/
UserDao ud = (UserDao) app.getBean("userDao11");
/*获取对象*/ /*强转对象*/
Object ud1 = app.getBean("userDao11");
ud.save();
2.引用数据
3.集合数据
/*定义变量、构造方法*/
private List<String> strList;
private Map<String , User> userMap;
private Properties properties;
public void setStrList(List<String> strList) {
this.strList = strList;
}
public void setUserMap(Map<String, User> userMap) {
this.userMap = userMap;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
/*实现接口的类的方法*/
public void save() {
System.out.println(strList);
System.out.println(userMap);
System.out.println(properties);
}
private String name;
private String addr;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", addr='" + addr + '\'' +
'}';
}
<bean id="userDao222" class="com.remli.dao.impl.UserDaoImpl" >
<!--属性注入-->
<property name="strList">
<list>
<value>任</value>
<value>明</value>
<value>任</value>
</list>
</property>
<property name="userMap">
<map><!--key value-->
<entry key="key1" value-ref="user11"> </entry>
<entry key="key2" value-ref="user22"> </entry>
</map>
</property>
<property name="properties">
<props>
<prop key="1">111</prop>
<prop key="2">1112</prop>
<prop key="3">1113</prop>
</props>
</property>
</bean>
<bean id="user11" class="com.remli.domain.User">
<property name="name" value="我是"></property>
<property name="addr" value="中国"></property>
</bean>
<bean id="user22" class="com.remli.domain.User">
<property name="name" value="我是1"></property>
<property name="addr" value="中国1"></property>
</bean>
/*获取文件流*/
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
/*接口*/ /*接口实现*/
UserDao u2= (UserDao) app.getBean("userDao222");
/*获取对象*/ /*强转对象*/
Object d2 = app.getBean("userDao222");
u2.save();
三、引入其他配置文件(分模块开发)
实际开发中,Spring的配置内容非常多,这导致Spring配置很繁杂,使用可以拆分到其它配置文件当
中,而且Spring主配置文件通过import标签加载
1、< import >标签
<!--主配置文件——引入分模块文件-->
<import resource="applicationContext-user.xml"></import>
applicationContext.xml
applicationContext-product.xml
applicationContext-user.xml
四、Spring的重点配置
1、< property >标签:属性注入、setter()
property:通过setter对应的方法注入。
<property>标签:属性注入
name属性:属性名称
value属性:注入的普通属性值
ref属性:注入的对象引用值
<list>标签
<map>标签
<properties>标签
1. name属性:属性名称
1. value属性:注入的普通属性值
1. ref属性:注入的对象引用值
1. < set >标签:集合——引用ref
<!-- 给set注入值 不能有相同的对象 -->
<property name="empSets">
<set>
<ref bean="emp1" />
<ref bean="emp2"/>
</set>
</property>
1. < list >标签:集合——引用ref
<!-- 给list注入值 可以有相同的多个对象 -->
<property name="strList">
<list>
<value>人</value>
<value>民</value>
<value>人</value>
</list>
</property>
1. < map >标签:集合——键值对
<!-- 给map注入值 只要map中的key值不一样就可以装配value -->
<property name="userMap">
<map><!--key value-->
<entry key="key1" value-ref="user11"> </entry>
<entry key="key2" value-ref="user22"> </entry>
</map>
</property>
1. < properties >标签:与map类似——键值对
<property name="properties">
<props>
<prop key="1">111</prop>
<prop key="2">1112</prop>
<prop key="3">1113</prop>
</props>
</property>
2、< constructor-arg >标签:指定构造函数的参数注入
constructor-arg:通过构造函数注入。
<!--找无参构造方法-->
<bean id="userDao" class="com.remli.dao.impl.UserDaoImpl">
</bean>
<bean id="userService" class="com.remli.service.impl.UserServiceImpl">
<!--参数名--> <!---->
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
constructor-arg属性通过指定type 类型来调用对应的构造函数,
<constructor-arg name="id" value="1"/>
<constructor-arg name="name" value="student"/>
<constructor-arg name="dream">
<list>
<value>soldier</value>
<value>scientist</value>
<value>pilot</value>
</list>
</constructor-arg>
<constructor-arg name="score">
<map>
<entry key="math" value="90"/>
<entry key="english" value="85"/>
</map>
</constructor-arg>
五、SpringAPI
1、ApplicationContext的继承
applicationContext:接口类型,代表应用上下文,可通过其实例获得Spring容器中的Bean对象。
2、ApplicationContext的实现类
1.ClassPathXmlApplicationContext:类 路径 文件类型 应用 上下文——resource下文件(相对)
它是从类的根路径下加载配置文件(常用)
/*获取文件流*/
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
/*接口*/ /*接口实现*/
2.FileSystemXmlApplicationContext:文件 系统 文件类型 应用 上下文——磁盘绝对路径
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任何位置。
ApplicationContext appp = new FileSystemXmlApplicationContext("C:\\Users\\REMLI\\IdeaProjects\\REM_SSMS\\src\\main\\resources\\applicationContext.xml");
3.AnnotationConfigApplicationContext:注解 配置 应用 上下文——注解开发
当使用注解配置容器对象时,需要使用此类来创建Spring容器。它用来读取注解。
3、getBean()方法的使用
1.强转类型
一个是通过id来获取:某一个类型可存在多个,获取后需要强转。
UserDao u111= (UserDao) appp.getBean("userDao222");
2.直接获取类对象:类文件直接指定
一个通过返回值来获取:一种类型只能有一个,获取后不需要强转。
UserDao userDao = app.getBean(UserDao.class);
3.通过java对象获取
Object d111 = appp.getBean("userDao222");
六、配置数据源
1 、数据源(连接池)的作用
1.提高程序性能
2.事先实例化数据源、初始化部分连接资
3.使用连接资源时从数据源中获取
4.使用完毕后将连接资源归还给数据源
常见数据源:DBCP,C3P0,BoneCP、Druid等
2 、引入相关坐标依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!--添加Druid依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
3、手动创建C3P0数据源:一定要注意空格、注意名称正确
@Test
/*测试手动创建c3p0数据源*/
public void test1() throws Exception {
/*创建数据源*/
/*康波坡尔*/
/*注意一个问题保证mysql语句的正确、Mysql 8.0.19和以前版本连接语句略微不同*/
/*实例化对象*/
ComboPooledDataSource dataSource = new ComboPooledDataSource();
/*对象调用方法——并set方法赋值*/
/*赋值驱动类数据库连接信息*/
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/remli?useSSL=false&serverTimezone=UTC");
dataSource.setUser("root");
dataSource.setPassword("2020");
/*创建对象获取连接信息*/
Connection connection = dataSource.getConnection();
/*打印对象信息*/
System.out.println("\n地址:"+connection);
/*连接关闭、归还资源*/
connection.close();
}
4、手动创建Druid数据源:一定要注意空格、注意名称正确
@Test
/*测试手动创建druid数据源*/
/*如果找不到DruidDataSource请在maven里清理clean里面的jar包*/
public void test2() throws Exception {
/*创建数据源*/
/*注意一个问题保证mysql语句的正确、Mysql 8.0.19和以前版本连接语句略微不同*/
/*实例化对象*/
DruidDataSource dataSource = new DruidDataSource();
/*对象调用方法——并set方法赋值*/
/*赋值驱动类数据库连接信息*/
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");/*存在耦合*/
dataSource.setUrl("jdbc:mysql://localhost:3306/remli?useSSL=false&serverTimezone=UTC");/*存在耦合*/
dataSource.setUsername("root");/*存在耦合*/
dataSource.setPassword("2020");/*存在耦合*/
/*创建对象获取连接信息*/
DruidPooledConnection connection = dataSource.getConnection();
/*打印对象信息*/
System.out.println(connection);
/*连接关闭、归还资源*/
connection.close();
}
5、手建C3P0(加载properties配置文件):注意空格、名称正确
1.创建代码:
@Test
/*测试手动创建c3p0数据源(加载properties配置文件)*/
public void test3() throws Exception {
/*读取配置文件*/
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
String driver = rb.getString("jdbc.driver");
String url = rb.getString("jdbc.url");
String username = rb.getString("jdbc.username");
String password = rb.getString("jdbc.password");
/*创建数据源对象、设置连接参数*/
/*康波坡尔*/
/*注意一个问题保证mysql语句的正确、Mysql 8.0.19和以前版本连接语句略微不同*/
/*实例化对象*/
ComboPooledDataSource dataSource = new ComboPooledDataSource();
/*对象调用方法——并set方法赋值*/
/*赋值驱动类数据库连接信息*/
/*注意值不能加双引号*/
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
/*创建对象获取连接信息*/
Connection connection = dataSource.getConnection();
/*打印对象信息*/
System.out.println("\n地址:"+connection);
/*连接关闭、归还资源*/
connection.close();
}
2.配置文件jdbc.properties:注意语句正确、空格、名称
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/remli?useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=2020
七、Spring配置数据源:DataSource——.set方法注入
将DataSource创建权——交给Spring容器完成
DataSource有无参构造方法——Spring默认通过无参构造方法实例化对象
使用DataSource获取数据库的连接对象——需通过set方法设置数据库连接信息——Spring可通过set方法进行字符串注入
1、application配置文件:配置连接信息——com.mchange.v2.c3p0.ComboPooledDataSource
1.注意一个问题:&会报错——写成&
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--set方法注入参数-->
<!--这里的名称是java里面的首字母小写-->
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/remli?useSSL=false&serverTimezone=UTC"></property>
<property name="user" value="root"></property>
<property name="password" value="2020"></property>
</bean>
2、代替ComboPooledDataSource——>ClassPathXmlApplicationContext
@Test
/*测试Spring容器产生数据源对象(加载application.xml配置文件)*/
public void test4() throws Exception {
/*读取配置文件*/
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
/*创建数据源对象、设置连接参数*/
/*实例化对象*/
DataSource dataSource4 = app.getBean(DataSource.class);
/*创建对象获取连接信息*/
Connection connection4 = dataSource4.getConnection();
/*打印对象信息*/
System.out.println("\n地址:"+connection4);
/*连接关闭、归还资源*/
connection4.close();
}
八、Spring单独配置数据源:xml加载properties文件——分开数据库与Spring
properties的键值对写法需要注意不要有键名相同!!!
各自的数据库——加载——对应properties文件
1、spring加载properties文件步骤:
1.引入context命名空间和约束路径:
applicationContext.xml加载jdbc.properties配置文件——获得连接信息
首先引入context命名空间和约束路径:
1命名空间:xmlns:context="http://www.springframework.org/schema/context"
context命名空间中有组件扫描和加载外部.properties文件的标签
加载到IOC中的.properties文件可以通过spring el表达式获取,格式为:${键名}
<context:component-scan />:配置组件扫描,可以扫描指定包下的注解
<context:property-placeholder />:加载外部的.properties文件到spring容器当中,
可以通过spel,即${}获取到值,例如配置数据库连接参数
xmlns:context="http://www.springframework.org/schema/context"
2约束路径:http://www.springframework.org/schema/context
约束路径1:http://www.springframework.org/schema/context
约束路径2:http://www.springframework.org/schema/context/spring-context.xsd
spring启动时需验证xml文档,约束的作用就是来验证配置文件的xml文档语法的正确性。
http://www.springframework.org/schema/context/spring-context.xsd
2.加载配置文件标签:< context:property-placeholder location="xx.properties"/ >
<context:property-placeholder />:加载外部的.properties文件到spring容器当中,
可以通过spel,即${}获取到值,例如配置数据库连接参数
<!--加载外部properties配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
3.< property name="" value="${key}"/ >:spr语言——EL
获取key值——获取properties对应名称值
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--set方法注入参数-->
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
4.DataSource.class
<!--解耦合-->
<!--这个地方可以更换数据源-->
<!--加载外部properties配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--set方法注入参数-->
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
@Test
/*测试Spring容器产生数据源对象(加载application.xml配置文件)*/
public void test4() throws Exception {
/*读取配置文件*/
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
/*创建数据源对象、设置连接参数*/
/*实例化对象*/
DataSource dataSource4 = app.getBean(DataSource.class);
/*创建对象获取连接信息*/
Connection connection4 = dataSource4.getConnection();
/*打印对象信息*/
System.out.println("\n地址4:"+connection4);
/*连接关闭、归还资源*/
connection4.close();
}
5.DruidDataSource.class
<!--解耦合-->
<!--这个地方可以更换数据源-->
<!--加载外部properties配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!--set方法注入参数-->
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
@Test
/*测试Spring容器产生数据源对象(加载application.xml配置文件)*/
public void test5() throws Exception {
/*读取配置文件*/
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
/*创建数据源对象、设置连接参数*/
/*实例化对象*/
DruidDataSource dr = app.getBean(DruidDataSource.class);
/*创建对象获取连接信息*/
Connection connection5 = dr.getConnection();
/*打印对象信息*/
System.out.println("\n地址5:"+connection5);
/*连接关闭、归还资源*/
connection5.close();
}
2者不能同时开启、会相互报错
总结:命名空间修改方法,赋值xmlns后的url,将beans改为context,然后建立新的xmlns:context。
复制前一段xsi:schemaLocation将所有的beans都改为context添加在后面。
引入文件路径,classpath表示class文件路径,resource文件默认保存在classpath文件下,
所以路径为"classpath:jdbc.properties"。
在xml中调用properties文件,使用EL表达式。
问题记录:
导入properties后,Druid报错:
[create connection SQLException,
url:jdbc:mysql://localhost:3306/demo, errorCode 1045, state 28000]
错误原因:properties配置文件中的名字与Driud属性名冲突。
修改前:
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/remli?useSSL=false&serverTimezone=UTC
username=root
password=2020
修改后:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/remli?useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=2020
九、Spring注解开发
语义化:见名知意
1、 Spring原始注解
Spring原始配置主要替代<Bean>的配置
@Component——id——实例化——随便那个——无语义
使用在类上用于实例化Bean
该组件用于Spring生成一个bean——>Component:组件
Component:组件 ByID
@Component("userDao")/*相当于配置文件id、定位类*/
@Component("userService")/*相当于配置文件id、定位类*/
@Controller——Web层控制类实例化——语义化
使用在web层类上用于实例化Bean
该控制器用于Spring生成一个bean
@Service——Service层服务类实例化——语义化
使用在service层类上用于实例化Bean
该业务逻辑类用于Spring生成一个bean
@Service("userService")/*相当于配置文件id、定位类*/
@Repository——id——Dao层数据存储类实例化——语义化
使用在dao层类上用于实例化Bean
该Dao类用于Spring生成一个bean——>repository:贮藏室 数据封装基地
Repository:贮藏室 ByID
@Repository("userDao")/*相当于配置文件id、定位类*/
@Controller
@Service
@Repository
@Component
4者无本质区别
他们存在是为区分开web、service、dao层
方便代码阅读。
@Autowired——无需Setter——字段按类型注入——可单独使用
类型
使用在字段上用于根据类型依赖注入
作用:自动封装该属性、或者字段
可不用Setter方法接收
单个类:独自使用
@Autowired
//单个使用——按照数据类型从Spring容器中匹配进行注入、注意单个数据类可以、多个就识别确定不了
结合@Qualifier使用:
@Autowired
//单个使用——按照数据类型从Spring容器中匹配进行注入、
//注意单个数据类可以、多个就识别确定不了
@Qualifier("userDao")
//按照id从容器中进行匹配
//但是此处需要结合@Autowired一起使用
@Qualifier——name/id——@Autowired+按名称注入——必须配合使用
id+name
结合@Autowired一起使用用于根据名称进行依赖注入
根据提供的修饰语 @Qualifier('xxx')——>匹配该xxx属性,
使用该注解,必须配合AutoWire一起使用,
Qualifier:修饰语 ByName
@Autowire
@Qualifier("user")
意义:封装user注解的bean为本类对象的成员,根据名称注入 ByName,设置在字段上.
@Qualifier常用在参数赋值上
如: String getUsername(@Qualifier("user")User user){}
结合@Qualifier使用:
@Autowired
//单个使用——按照数据类型从Spring容器中匹配进行注入、
//注意单个数据类可以、多个就识别确定不了
@Qualifier("userDao")
//按照id从容器中进行匹配
//但是此处需要结合@Autowired一起使用
@Autowired
@Qualifier("userDao")
@Resource——按名称注入=@Autowired+@Qualifier——J2EE提供
相当于@Autowired+@Qualifier, 按照名称进行注入
Resource是Aotuwire注解和Qualifier注解的结合体.@Resource("user"),标注为user的bean
@Resource("user") 封装user注解的bean为奔雷对象的成员 ==
@Autowire
@Qualifier
默认根据名称依赖注入,
默认Resource() = Resource like Resource(name = "XXX")——>体现面向对象思想
应该设置在字段上
可以手动设置为根据类型注入Resource(type = User.class)——>体现面向对象思想
应该设置在set方法上
@Resource(name="userDao")
//相当于 @Autowired+@Qualifier("userDao")
@Value——注入普通属性
注入普通属性
@Value("xxx");为修饰字段赋值;
通常配合SpEL(Spring Expression Language)使用
@Value("${jdbc.url}") private String url; 为url赋值
——> (Spring中引入的properties后缀文件中的jdbc.url对应的值)
——>或者{PropertySrouce注解中的jdbc.url值}
@Value("value注入成功")//属性值注入
private String vals;
@Value("${jdbc.driver}")//数据库属性值注入
private String sjk;
@Scope——Bean作用范围
标注Bean的作用范围
常用 : @Scope("singleton") 声明从spring容器获得的该类的bean
有且只有一个(单例模式)
@Scope("prototype") 声明从spring容器获得的该类的bean
有多个(标准Bean模式)
@Scope("prototype")//多例
//@Scope("singleton")//单例
@PostConstruct——Bean初始化方法——构造后
使用在方法上标注该方法是Bean的初始化方法
注解使用在用户定义的初始化方法前,
声明该方法是该类的初始化方法
@PostConstruct :意为执行在构造方法后,构造方法创建对象,对象调用该初始化方法
@PostConstruct
public void init(){
System.out.println("Service对象初始化方法");
}
@PreDestroy——Bean销毁方法——销毁前
使用在方法上标注该方法是Bean的销毁方法
注解使用在用户自定义的结束方法前,
声明该方法是该类的结束方法,
当前对象被销毁前调用该方法
@PreDestroy ;Spring容器被销毁的时候,执行.
@PreDestroy
public void destory(){
System.out.println("Service对象销毁方法");
// /*读取配置文件*/
// /*子类实现销毁方法——手动关闭*/
// ClassPathXmlApplicationContext apps = new ClassPathXmlApplicationContext("applicationContext.xml");
//
// /*创建数据源对象、设置连接参数*/
// /*实例化对象*/
// XXX drs = app.getBean(XXX.class);
//
// /*手动关闭*/
// drs.close();
}
@Order——注入对象引用集合
注入对象引用的集合的时候使用:
@Order(1)
@Order(2) 表示该类生成的bean将会存储在某个List<该类型>中,并按照顺序插入List
如果是Map<String,T> 那么order的顺序没有任何关系,
但是该Map必须定义为<String,T> String接收对应对象的id值(id唯一 ——> key唯一);
此处的List和Map可以通过@Autowired或@Resource注入;
2、组件扫描:component-scan
注意:注解开发时需在applicationContext.xml中配置组件扫描
作用::指定哪一个包及其包下的Bean需要扫描以便识别使用注解配置的类和方法
包:基础包+包括里面的子包
<!--注解开发——需要配置组件扫描-->
<!--组件扫描——扫描指定文件夹下的包-->
<context:component-scan base-package="com.remli"/>
3、2种配置/注解方式对比:
1.原始xml配置方式
<!--xml配置-->
<bean id="userDao" class="com.remli.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.remli.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
public interface UserDao {
public void start();
}
public class UserDaoImpl implements UserDao {
public void start(){
System.out.println("启动程序1·····");
}
}
public interface UserService {
public void start();
}
public class UserServiceImpl implements UserService {
private UserDao userDao;
/*Setter方法*/
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void start(){
System.out.println("程序启动2·····");
}
}
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = app.getBean(UserService.class);
userService.start();
}
}
2.注解@方式!!!
<!--注解开发——需要配置组件扫描-->
<!--组件扫描——扫描指定文件夹下的包-->
<context:component-scan base-package="com.remli"/>
public interface UserDao {
public void start();
}
/*xml配置定位类文件位置*/
/*
<bean id="userDao" class="com.remli.dao.impl.UserDaoImpl"></bean>
*/
/*注解*/
/*
@component
*/
@Component("userDao")/*相当于配置文件id、定位类*/
public class UserDaoImpl implements UserDao {
public void start(){
System.out.println("启动程序1·····");
}
}
public interface UserService {
public void start();
}
/*xml配置定位类文件位置*/
/*
<bean id="userService" class="com.remli.service.impl.UserServiceImpl"></bean>
*/
/*注解*/
/*
@component
*/
@Component("userService")/*相当于配置文件id、定位类*/
public class UserServiceImpl implements UserService {
/*xml配置注入属性*/
/*
<property name="userDao" ref="userDao"></property>
*/
/*注解——注入*/
/*
@Autowired
@Qualifier("userDao")
*/
@Autowired
@Qualifier("userDao")
private UserDao userDao;
/*Setter方法*/
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void start(){
System.out.println("程序启动2·····");
}
}
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = app.getBean(UserService.class);
userService.start();
}
}
2、Spring新注解
@Configuration——指定类为Spring配置类
用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解
@ComponentScan——指定Spring初始化容器扫描包
用于指定Spring在初始化容器时要扫描的包
作用和在Spring的xml配置文件中的
<context:component-scan base-package=”com.code_g”/>一样
ComponentScan:组件扫描 ByPackage ComponentScan:在使用全注解的时候,非常重要.如果未配置,那么Spring的IoC容器默认不会扫描任何包,就不会有任何Bean.
@Bean——方法返回值存储到Spring容器中
使用在方法上,标注将该方法的返回值存储到Spring容器中
@PropertySource——加载properties文件配置
用于加载.properties文件中的配置
@Import——导入其他类配置
用于导入其他配置类
3、Spring对象创建——实例化——找到类创建对象——所在位置
@Component——随便
定义Bean, 不好归类时使用
@Controller——web视图控制层
@Controller("Bean的名称")
定义控制层Bean,如Action
@Service——Service业务服务层
@Service("Bean的名称")
定义业务层Bean
@Repository——Dao数据持久化层
@Repository("Bean的名称")
定义DAO层Bean
4、Spring注入
1.对象注入:依据、bean(id)=name、类、属性注入
@Resource:默认按名称byName注入——(J2EE提供注解)——需添加其依赖
Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。
默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来注入。
它有两个属性是比较重要的:
如果想减少对 Spring 的依赖建议使用 @Resource 方法。
<!--Resource注解依赖-->
<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<!-- Javax Annotation -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
1name: Spring 将 name 的属性值解析为 bean 的名称, 使用 byName 的自动注入策略
2type: Spring 将 type的属性值解析为 bean 的类型,使用 byType 的自动注入策略
3反射—— byName 自动注入策略
如果既不指定 name 属性又不指定 type 属性,Spring这时通过反射机制使用 byName 自动注入策略
@Resource 装配顺序:
如果同时指定了 name 属性和 type 属性,那么 Spring 将从容器中找唯一匹配的 bean 进行装配,找不到则抛出异常
如果指定了 name 属性值,则从容器中查找名称匹配的 bean 进行装配,找不到则抛出异常
如果指定了 type 属性值,则从容器中查找类型匹配的唯一的 bean 进行装配,找不到或者找到多个都会抛出异常
如果都不指定,则会自动按照 byName 方式进行装配, 如果没有匹配,则回退一个原始类型进行匹配,如果匹配则自动装配
@Autowried:默认按类型byType注入
默认是按照类型进行装配注入,
默认情况下,它要求依赖对象必须存在,如果允许 null 值,可以设置它 required 为false。
如果我们想要按名称进行装配的话,可以添加一个 @Qualifier 注解解决。
@Autowired 接口只能有一个实现类,通过byType方式注入
默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false)
@Autowried
@Qualifier("adminDAO")
private AdminDAO adminDAO;
@Qualifier:默认类名
spring的注解,按名字注入 一般当出现两个及以上bean时,不知道要注入哪个,作为@Autowired()的修饰用
@Qualifier 接口可以有多个实现类,可以按实现类的类名进行注入
2.普通属性注入:——Value
通常不直接赋值,而是调用引入的properties文件赋值。
只要核心类或者引入的子类引入了properties文件就可以直接用EL表达式。
引入格式为EL表达式
使用@Value将外部值动态的注入到Bean中,使用情况:
注入普通字符串
注入操作系统属性
注入表达式结果
注入其他Bean属性:注入beanInject对象的属性another
注入文件资源
注入URL资源
@Value("${jdbc.username}")
private String name;
@Value("normal")
private String normal; // 注入普通字符串
@Value("#{systemProperties['os.name']}")
private String systemPropertiesName; // 注入操作系统属性
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private double randomNumber; //注入表达式结果
@Value("#{beanInject.another}")
private String fromAnotherBean; // 注入其他Bean属性:注入beanInject对象的属性another,类具体定义见下面
@Value("classpath:com/hry/spring/configinject/config.txt")
private Resource resourceFile; // 注入文件资源
@Value("http://www.baidu.com")
private Resource testUrl; // 注入URL资源