spring框架Day01
spring的开发步骤
-
导入坐标
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency>
-
创建Bean
-
创建applicationContext.xml
-
在配置文件中经行配置
<!--id名字 访问的权限路径--> <bean id="user" class="com.itheima.dao.Impl.UserDaoImpl"></bean>
-
创建ApplicationContext对象,调用getBean方法
//第一步 ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); //采用getBean方法 得到userDao, UserDao user = (UserDao) app.getBean("user"); user.saveUser();
-
Scope:值对象的作用范围,取值如下:
-
singleton : 默认值,单例的(user1和user2得到的会是同一个内存地址)(在加载配置文件的时候创建对象)
//第一步 ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); //采用getBean方法 得到userDao, UserDao user1 = (UserDao) app.getBean("user"); UserDao user2 = (UserDao) app.getBean("user"); System.out.println(user1); System.out.println(user2);
-
prototype: 多列的(user1和user2不是同一个雷车地址)(在调用getBean的时候创建对象,调用几次getBean就创建几次)
-
//第一步 ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); //采用getBean方法 得到userDao, UserDao user1 = (UserDao) app.getBean("user"); UserDao user2 = (UserDao) app.getBean("user"); System.out.println(user1); System.out.println(user2);
-
-
Bean实例化的三种方式
-
无参构造方法(重点)
-
上面的都是用无参构造
-
-
静态工厂实例化
-
先创建一个工厂java
public class StaticFactory { //静态的方法 public static UserDao getUserDao(){ return new UserDaoImpl(); } }
-
applicationContext.xml文件的配置
<bean id="user" class="com.itheima.factroy.StaticFactory" factory-method="getUserDao"></bean>
-
text程序 代码不变 , 输出的和无参构造输出的一样
-
-
工厂实力方法实例化
-
第一步先创建一个工厂里面有一个非静态的方法
public class DynamicFactory { //非静态的 public UserDao getUserDao(){ return new UserDaoImpl(); } }
-
第二部,在applicationContext.xml文件中配置,但是由于是非静态的方法,不能直接调用,而是必须现有这个对象
<!--因为是非静态的所以不能直接的调用他的方法,也不能用第一种方式,创建无参构造,所以我们需要先创建工厂对象--> <bean id="factory" class="com.itheima.factroy.DynamicFactory" ></bean> <!--在通过获取上面这个对象,在调用getUserDao方法--><!--factory-bean="factory"就是用来表名从哪里获取对象--> <bean id="user" factory-bean="factory" factory-method="getUserDao"></bean>
-
text代码不变,输出的于无参构造一样
-
-
在Service 同样通过配置文件来调用Dao层的saveuser方法 (Bean的依赖注入)
-
第一步先创建一个UserService接口和UserService接口实现类(实现类中通过配置文件来创建Dao层的对象和调用saceUser方法)
public interface UserService { public void save(); }
public class UserServiceImpl implements UserService { @Override public void save() { //通过配置文件来创建获取UserDao对象,并且调用他的方法 ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao) app.getBean("user"); userDao.saveUser(); } }
-
第二部创建一个 ,test类(同样利用配置文件来创建UserService对象,并且掉用方法)
public class ControllerTest { public static void main(String[] args) { //同样的通过配置文件来获取UserService对象,并且调用他的sava方法 ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) app.getBean("userService"); userService.save(); } }
-
第三步:配置文件代码
<bean id="user" class="com.itheima.dao.Impl.UserDaoImpl"></bean> <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"></bean>
将Dao层注入给Service层
Set方法注入
-
教Dao层注入给Service层,这样就不需要在SErvice层中在编写获得Dao层的Bean,而是在spring中,直接调用set方法,获取到Dao层的UserDao
-
第一步:Dao层代码不变
-
第二步:Service实现层,私有一个UserDao属性,并且给出set方法
public class UserServiceImpl implements UserService { private UserDao userDao; //采用set的方法,在spring中将Dao层注入给Service层,这样的话就不用下面代码了 //set方法! public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void save() { //通过配置文件来创建获取UserDao对象,并且调用他的方法 /* ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao) app.getBean("user");*/ userDao.saveUser(); }
-
spring配置文件中,用set方法将UserDao注入
<bean id="user" class="com.itheima.dao.Impl.UserDaoImpl"></bean> <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"> <!--这里的name是set方法的中set的后面几个单词,但是!第一个字母改小写, 这里的ref是Dao层的Bean的唯一表示Id的值--> <property name="userDao" ref="user"></property> </bean>
注意!如果直接new 一个 UserServiceImpl对象 然后调用save方法 会有空指针异常,因为你new的这个对象,他没有结果spring配置文件,所以他的userDao没有被注入,所有userDao为空
//注意!这里如果你直接new 一个UserServiceImpl对象 然后调用save方法 会有空指针异常 UserService userService1= new UserServiceImpl(); userService1.save();
Set方法配置文件的简便用法!
-
第一步:前面的java文件代码都不变
-
第二步,在spring配置文件中的上面输入 xmlns:p="http://www.springframework.org/schema/p"
<?xml version="1.0" encoding="UTF-8"?> <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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
-
Dao和Seivice的Bean:Dao的Bean不变, Service的改变(userDao-ref=)后面是注入的对象
<bean id="user" class="com.itheima.dao.Impl.UserDaoImpl"></bean> <!-- <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"> <!–这里的name是set方法的中set的后面几个单词,但是!第一个字母改小写, 这里的ref是Dao层的Bean的唯一表示Id的值–> <property name="userDao" ref="user"></property> </bean> --> <bean id="userService" class="com.itheima.service.impl.UserServiceImpl" p:userDao-ref="user"/>
-
有参构造方法注入
-
在Service的实现类里面创建有参构造和无参构造
public UserServiceImpl() { } public UserServiceImpl(UserDao userDao) { this.userDao = userDao; }
-
在spring配置文件中,将Dao注入(constructor(构造)arg(参数)这里name是有参构造的参数值!, ref是Dao的Bean的唯一标识Id值 )
<bean id="user" class="com.itheima.dao.Impl.UserDaoImpl"></bean> <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"> <!--constructor(构造)arg(参数)这里name是有参构造的参数值!, ref是Dao的Bean的唯一标识Id值 --> <constructor-arg name="userDao" ref="user"></constructor-arg> </bean>
在Dao层中定义两个私有属性,在spring中给他们赋值
set方法赋值
-
第一步:先定义两个属性,并且给出set方法
private String username; private Integer age; //注入两个普通的数据类型, 然后在spring配置文件经赋值 public void saveUser(){ //如果username个age有值,证明注入成功 System.out.println(username+"="+age); System.out.println("保存成功 "); } public void setUsername(String username) { this.username = username; } public void setAge(Integer age) { this.age = age;
-
第二步:在spring配置文件中注入值
<bean id="user" class="com.itheima.dao.Impl.UserDaoImpl"> <!--老规矩,属性 property--> <property name="username" value="zhangsan"/> <property name="age" value="22"/> <!--这里为什么不用ref,因为ref是用来注入对象的,这里是普通的属性--> </bean>
-
第三步:Service 不变.
有参构造注入值
-
第一步,在Dao层编写有参构造
private String username; private Integer age; //注入两个普通的数据类型, 然后在spring配置文件经赋值 public UserDaoImpl() { System.out.println("UserDaoImpl创建"); } public UserDaoImpl(String username, Integer age) { this.username = username; this.age = age; } public void saveUser(){ //如果username个age有值,证明注入成功 System.out.println(username+"="+age); System.out.println("保存成功 "); }
-
第二步:在spring层中赋值
<bean id="user" class="com.itheima.dao.Impl.UserDaoImpl"> <constructor-arg name="username" value="zhangsan"/> <constructor-arg name="age" value="22"/> </bean>
定义集合,并且为集合赋值
-
第一步先创建一个User类 提供私有属性name和age 并且提供set和get方法
public class User { private String name; private String addr;
-
第二部,在Dao层 定义三个集合 并且提供set和get方法
private List<String> stringList; private Map<String, User> userMap; private Properties properties;
-
第三步:在spring配置文件中经行赋值 ,先给user写上Bean标签
<bean id="user" class="com.itheima.dao.Impl.UserDaoImpl"> <!--老规矩,属性 property--> <!-- <property name="username" value="zhangsan"/> <property name="age" value="22"/>--> <!--这里为什么不用ref,因为ref是用来注入对象的,这里是普通的属性--> <constructor-arg name="username" value="zhangsan"/> <constructor-arg name="age" value="22"/> <property name="stringList"> <list> <value>aaa</value> <value>bbb</value> <value>ccc</value> </list> </property> <property name="userMap"> <map> <entry key="u1" value-ref="user1"></entry> <entry key="u2" value-ref="user2"></entry> </map> </property> <property name="properties"> <props> <prop key="zz" >dd</prop> <prop key="hh" >cc</prop> </props> </property> </bean> <bean id="user1" class="com.itheima.pojo.User"> <property name="name" value="zhangsan"></property> <property name="addr" value="cq"></property> </bean> <bean id="user2" class="com.itheima.pojo.User"> <property name="name" value="lisi"></property> <property name="addr" value="sichuan"></property> </bean>
其中注意 普通属性,像名字啊,年龄,这种都是用value ,对象采用ref 其中的value-ref是map集合中因为Users对象,也是value值,所以采用value-ref
spring配置文件引入其他配置文件
-
因为在实际开发的过程中,spring文件里面的东西或超级无敌的多,于是我们可以将这些代码分别写在其他的配置文件中,如将Dao层的写在applicationContext-Dao ,Service层的写在applicationContext-Service 这样,这样只需要一个主文件applicationContext,引入其他的文件,就可以安全运行
<!--映入其他两个spring配置文件--> <import resource="applicationContext-Dao.xml"/> <import resource="applicationContext-Service.xml"/>
读取spring配置文件的方式
-
第一种方式:采用 ClassPathXmlApplicationContext
//同样的通过配置文件来获取UserService对象,并且调用他的sava方法 ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
-
第二种方式:采用FileSystemXmlApplicationContext
//采取从磁盘读取applicationContext.xml 这种方式,如果项目变了位置就不适合了 ApplicationContext app = new FileSystemXmlApplicationContext("D:\\maven\\maven- demp\\src\\main\\resources\\applicationContext.xml");
-
如果你的某一个实现类的Bean只有一个比如下面,只有这一个 那么可以采用
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl"> <!--constructor(构造)arg(参数)这里name是有参构造的参数值!, ref是Dao的Bean的唯一标识Id值 --> <constructor-arg name="userDao" ref="user"></constructor-arg> </bean>
那么可以采用将所需要的数据类型传进去的这种方式来调用方法,这种方式不用转型
UserService userService = app.getBean(UserService.class); userService.save();
如果你的某一个实现类的Bean有多个,id值即使不相等,如下
<!--有参构造的注入方法,将Dao注入Service--> <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"> <!--constructor(构造)arg(参数)这里name是有参构造的参数值!, ref是Dao的Bean的唯一标识Id值 --> <constructor-arg name="userDao" ref="user"></constructor-arg> </bean> <bean id="userService2" class="com.itheima.service.impl.UserServiceImpl"> <!--constructor(构造)arg(参数)这里name是有参构造的参数值!, ref是Dao的Bean的唯一标识Id值 --> <constructor-arg name="userDao" ref="user"></constructor-arg> </bean>
那么采取这种方式来获取, 需要转型, 如果采取传入数据类型这种方式会报错 因为上面那种方式传入的是数据类型,而系统无法确认,你到底要执行是哪一个Bean 所以出错, 下面这种方式 传入的是id值,具有唯一性
UserService userService = (UserService) app.getBean("userService");
采用spring配置文件来连接数据库
-
先采用c3p0这个数据库连接池来连接数据库
-
第一步:先创建一个jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/book jdbc.username=root jdbc.password=xjj168
-
第二步:java文件
@org.junit.Test public void test1() throws Exception { //采用c3p0的连接池来获取数据库连接 ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc"); String driver = resourceBundle.getString("jdbc.driver"); String url = resourceBundle.getString("jdbc.url"); String username = resourceBundle.getString("jdbc.username"); String password = resourceBundle.getString("jdbc.password"); //获取连接 ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass(driver); dataSource.setJdbcUrl(url); dataSource.setUser(username); dataSource.setPassword(password); Connection conn = dataSource.getConnection(); System.out.println(conn); conn.close(); }
-
上面这种方法,普教普通,我们现在想要通过spring配置文件来帮助我们连接,spring配置文件中class里面的这个路径在启动时,会创建这个对象,并且调用他的无参构造,那么
ComboPooledDataSource dataSource = new ComboPooledDataSource();
-
这一步,我们就可以把他写进spring配置文件里面
-
第一步:先创建一个jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/book jdbc.username=root jdbc.password=xjj168
-
第二部,创建applicationContext.xml文件(里面name的值就是set后面的方法名)
<bean id="dataResource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/book"/> <property name="user" value="root"/> <property name="password" value="xjj168"/> </bean>
-
第三步:在java文件中创建ApplicationContext 调用getBean
public void test3() throws Exception { //采用spring配置文件来获取连接 ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); ComboPooledDataSource dataResource = (ComboPooledDataSource) app.getBean("dataResource"); //或者 // DataSource dataResource = app.getBean(DataSource.class); Connection connection = dataResource.getConnection(); System.out.println(connection); connection.close();
将applicationContext.xml文件和jdbc.properties文件结合
-
根据上面的情况,虽然我们已经很大程度的解耦合了,但是jdbc文件和applicationContext文件依旧没有联系,我们不防,让每一个文件都做自己的是,更大程度的解耦合,于是我们要引入jdbc文件到applicationContext中
-
第一步:先配置 在最开始的上面加入( xmlns:context="Index of /schema/context") 并且在 xsi:schemaLocation的“”中加入( Index of /schema/context http://www.springframework.org/schema/context/spring-context.xsd),第一个加入的其实就是复制的xmlns的后面的网址,在前面加了:context 把最后的Beans改成了context ,第二个网址,其实就是复制的他前面的那个网址,然后把里面所有的Bens改成了context
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd ">
-
第二步,导入jdbc.properties
<!--加载外部的properties文件--> <context:property-placeholder location="classpath:jdbc.properties"/>
-
第三步:再导入之后,我们就可以将我们原本写的value里面的值,用jdbc的来代替,用el表达式${key}通过key来获取value值
<bean id="dataResource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <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>