Spring ioc
简答理解:spring提供工厂创建对象,我们只需要告诉spring需要创建哪些对象即可
创建maven工程
然后确定代码存放路径,点击finish一个项目就创建成功了
项目的目录结构
spring IOC入门案例
编写项目三层对象
1.持久层
dao接口
package com.KkaBum.dao;
public interface UserDao {
void save();
}
dao接口实现类
package com.KkaBum.dao.impl;
import com.KkaBum.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("save用户");
}
}
2.业务层
service接口
package com.KkaBum.service;
public interface UserService {
void register();
}
service接口实现类
package com.KkaBum.service.impl;
import com.KkaBum.dao.UserDao;
import com.KkaBum.dao.impl.UserDaoImpl;
import com.KkaBum.service.UserService;
public class UserServiceImpl implements UserService {
UserDao userDao = new UserDaoImpl();
@Override
public void register() {
userDao.save();
}
}
3.web层
package com.KkaBum.web;
import com.KkaBum.service.impl.UserServiceImpl;
public class UserServlet {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
userService.register();
}
}
通过springioc进行改造项目
pom导包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.KkaBum</groupId>
<artifactId>spring01</artifactId>
<version>1.0.0</version>
<!--依赖版本-->
<properties>
<!-- spring版本 -->
<spring.version>5.0.6.RELEASE</spring.version>
</properties>
<!--依赖包-->
<dependencies>
<!--spring ioc依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
更改web层的代码
package com.KkaBum.web;
import com.KkaBum.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserServlet {
public static void main(String[] args) {
//之前的代码
//UserServiceImpl userService = new UserServiceImpl();
//userService.register();
/******************分割线**********************/
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
UserService userService = (UserService) ac.getBean("userService");
userService.register();
}
}
在resources目录下新建一个xml配置文件,applicationContext.xml
配置文件模板: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">
<!--
<bean id="" class=""></bean>
标签:
bean:配置javaBean对象,装备对象到spring容器
属性:
id:bean的唯一标识名称
class:类的全路径信息
-->
<bean id="userService" class="com.KkaBum.service.impl.UserServiceImpl"></bean>
</beans>
Spring工厂类结构
BeanFactory与ApplicationContext区别
#BeanFactory与ApplicationContext区别:
1.BeanFactory是顶层接口
2.ApplicationContext是子接口
3.它们最大的区别是创建对象的时间不一样:(只针对单例)
3.1.BeanFactory采用的是延迟加载的思想。即什么时候使用对象,什么时候创建(项目启动快,但是访问需要等待)
3.2.ApplicationContext采用立即创建的思想。即一加载配置文件,立即就创建(项目启动慢,但是访问快,所以常用)
bean标签作用
#bean标签作用:
配置javaBean对象。
【话外音】
spring框架遇到bean标签,默认调用无参数构造方法实例化对象。
bean标签的细节
bean:装配对象到spring容器
id:bean的唯一标识
class:就是实现类对象的地址,
scope: 作用范围,(bean的出生和死亡)
singleton: 单例(默认),
工厂创建时,创建对象。
工厂销毁时销毁对象。
prototype : 多例,
第一次获取对象时,创建对象。
工厂销毁时,对象是没有被销毁的。
只能由java的垃圾回收机制回收。
init-method: 对象初始化时将要调用的方法
destroy-method: 对象销毁时,将要调用的方法
最终我们需要掌握:
1.bean标签的个属性的含义。
2. 在后期的ssm框架开发中,我们的service,dao,controller 都是单例。
spring创建对象的三种方式
1.默认无参构造
<bean id="userService" class="com.KkaBum.service.impl.UserServiceImpl"></bean>
2.工厂静态方法
创建一个utils包,然后在utils包下新建两个类,BeanFactory和BeanFactory2
BeanFactory
package com.KkaBum.utils;
import com.KkaBum.dao.UserDao;
import com.KkaBum.dao.impl.UserDaoImpl;
public class BeanFactory {
public static UserDao getUserDao(){
return new UserDaoImpl();
}
}
BeanFactory2
package com.KkaBum.utils;
import com.KkaBum.dao.UserDao;
import com.KkaBum.dao.impl.UserDaoImpl;
public class BeanFactory2 {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
在test文件夹下创建一个测试类
SpringIocTest
package com.KkaBum.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringIocTest {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Object userDao = ac.getBean("userDao");
System.out.println("userDao = " + userDao);
}
}
applicationContext.xml
<!--工厂静态方法
class:工厂类的地址
factory-method:工厂的方法
-->
<bean id="userDao" class="com.KkaBum.utils.BeanFactory" factory-method="getUserDao"></bean>
运行结果:
3.工厂动态方法
动态方法的调用依赖对象所以先创建对象,再调用对象的方法
<!--先创建工厂对象-->
<bean id="factoryBean2" class="com.KkaBum.utils.BeanFactory2"></bean>
<!--再调用工厂对象的方法创建userDao对象-->
<bean id="userDao2" factory-method="getUserDao" factory-bean="factoryBean2"></bean>
测试类
package com.KkaBum.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringIocTest {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Object userDao = ac.getBean("userDao2");
System.out.println("userDao2 = " + userDao);
}
}
运行结果
依赖注入(spring创建对象时给成员变量赋值)
1.构造
需要提供有参构造方法
<!--通过构造进行依赖注入
1,确定哪个参数
name:成员变量名
index:索引
type:通过类型
2,赋值
value:基本类型参数
ref:引用类型参数
-->
<bean id="userService" class="com.KkaBum.service.impl.UserServiceImpl">
<constructor-arg name="gameName" value="LOL"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="userDao" ref="userDao2"></constructor-arg>
</bean>
2.set
需要提供set方法
<!--通过构造进行依赖注入
name:set方法的后面的名字
-->
<bean id="userService" class="com.KkaBum.service.impl.UserServiceImpl">
<property name="gameName" value="LOL"></property>
<property name="userDao" ref="userDao2"></property>
<property name="age" value="1818"></property>
</bean>
依赖注入的简写方式(了解)
p名称空间注入
<!--p名称空间注入,说明:
第一步:导入p名称空间
xmlns:p="http://www.springframework.org/schema/p"
第二步:
p:属性名称 ==>给java简单类型成员变量赋值
p:属性名称-ref ==>给其他bean类型成员变量赋值
-->
<bean id="pDao" class="com.KkaBum.dao.impl.SetDaoImpl"
p:id="3" p:name="小王" p:age="18" p:birthday-ref="now"
></bean>
c名称空间注入
<!--c名称空间注入,说明:
第一步:导入c名称空间
xmlns:c="http://www.springframework.org/schema/c"
第二步:
c:属性名称 ==>给java简单类型成员变量赋值
c:属性名称-ref ==>给其他bean类型成员变量赋值
-->
<bean id="cDao" class="com.KkaBum.dao.impl.ConstructorDaoImpl"
c:id="4" c:name="小黄" c:age="18" c:birthday-ref="now"
></bean>
spring基于注解的ioc开发
常用注解
创建对象相关的注解
@Component
#作用:
配置javaBean对象。相当于xml配置方式中的bean标签
#属性:
value:给bean一个唯一标识名称
#细节:
1.value属性可以省略
2.默认使用类的名称首字母小写,作为bean的名称
@Controller、@Service、@Repository
#由@Component演化的三个注解:
@Controller:一般用于表现层
@Service:一般用于业务层
@Repository:一般用于持久层
【话外音】
它们都是@Component的儿子,是三兄弟
设置bean作用范围相关的注解
@Scope
#作用:
设置bean的作用范围。相当于xml配置方式中bean标签的scope属性
#属性:
value:指定作用范围取值
属性取值:
singleton:单例。默认值
prototype:多例
request:web项目中,把bean对象存入request域中【了解】
session:web项目中,把bean对象存入session域中【了解】
globalsession:web项目中,把bean对象存入全局session域中【了解】
使用注解需要在applicationContext.xml配置文件中设置注解扫描
<!--配置注解扫描,扫描指定包下的注解
base-package:包的路径
-->
<context:component-scan base-package="com.KkaBum"></context:component-scan>
注入数据相关的注解
@Autowired
#作用:
默认按照bean的类型注入数据
#属性:
required:指定目标bean是否必须存在于spring的IOC容器(true必须存在;false:可以不存在;默认true)
#细节:
1.在spring容器中,如果同一个类型存在多个bean实例对象
2.则先按照bean的类型进行注入,再按照bean的名称进行匹配
3.匹配上注入成功;匹配不上注入失败
@Qualifier
#作用:
与@Autowired注解一起使用,指定在按照bean类型注入的基础上,再按照bean的名称注入
#属性:
value:指定bean的名称
#细节:
1.在类的成员变量上,不能单独使用。需要与@Autowired注解一起使用
2.在方法的成员变量上,可以单独使用
@Resource
#作用:
默认按照bean的名称注入数据
#属性:
name:指定bean的名称注入数据
type:指定bean的类型注入数据
#细节:
默认按照bean的名称匹配注入数据。如果注入失败,再按照bean的类型注入
#例子:
@Resource(name="userDao")
@Resource(type=UserDao.class)
与bean生命周期相关的注解
#@PostConstruct:
初始化操作,相当于xml配置方式中bean标签的init-method属性
#@PreDestroy:
销毁操作,相当于xml配置方式中bean标签的destroy-method属性
包扫描的注解
@ComponentScan
#作用
通过@ComponentScan 注解来配置包扫描
@ComponentScan("com.KkaBum")
相当于xml配置中的:
<context:component-scan base-package="com.KkaBum"></context:component-scan>
其他注解
@Configuration
#作用
声明当前类是一个配置类
@Import
#作用
导入其他配置类
@Import(JbdcConfig.class)
@PropertySource
#作用
导入配置文件
@PropertySource("classpath:jdbc.properties")