Spring学习
Spring基础:
创建Spring配置文件,配置对应类作为Spring管理的bean
<bean …………>
例子:
<bean id="dao" class="com.jsoft.dao.impl.DaoImpl"></bean>
<bean id="service" class="com.jsoft.service.impl.ServiceImpl"></bean>
bean标签表示配置bean
id属性表示给bean定义类型(id不能重复)
class属性表示给bean定义类型
初始化对应的Ioc容器,并从容器中获取bean:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Dao dao = (Dao) applicationContext.getBean("dao");
Service service = (Service) applicationContext.getBean("service");
service.MethodService();
System.out.println("--------------");
dao.MethodDao();
DI(控制反转):
- 使用Ioc管理bean
- Service层中不再使用new的方式创建Dao对象
- Service中需要的Dao的对象通过一个方法
- 用“配置”来描述Dao与Service的关系
在Serice中,删除new的Dao,并且为Dao方法提供set方法
private DaoImpl dao;
@Override
public void MethodService() {
System.out.println("Service方法执行了");
dao.MethodDao();
}
public void setDao(Dao dao){
this.dao = (DaoImpl) dao;
}
配置service与dao之间的关系:
<bean id="service" class="com.jsoft.service.impl.ServiceImpl">
<property name="dao" ref="dao">
(property标签表示配置当前bean的属性
name 表示配置哪一个具体的属性
ref属性表示参照哪一个bean)
</property>
</bean>
bean的别名:
bean的基础配置:
类名 | 描述 |
---|---|
名称 | name |
类型 | 属性 |
所属 | bean标签 |
功能 | 定义bean的别名,可定义多个,可以使用 逗号,分号; 空格 来分隔 |
例子
<bean id="dao" name="dao2 MyDao" class="com.jsoft.dao.impl.DaoImpl"></bean>
如果没有获取到,将抛出异常NoSuchBeanDefinitionException
bean的作用范围:
你造的对象是不是单例的?
Dao dao = (Dao) applicationContext.getBean("MyDao");
Dao dao1 = (Dao) applicationContext.getBean("MyDao");
System.out.println(dao);
System.out.println(dao1);
得出两个一模一样的地址:
我们在对应的bean标签中使用scope标签来让他不是单例模式
<bean id="dao" name="dao2 MyDao" class="com.jsoft.dao.impl.DaoImpl" scope="prototype"></bean>
可以让我们刚才创建的两个dao的地址不同
类别 | 描述 |
---|---|
名称 | scope |
类型 | 属性 |
所属 | bean标签 |
功能 | 1.定义bean的作用范围, singleton:单例(默认) prototype(非单例) |
范例 | <bean id="dao" name="dao2 MyDao" class="com.jsoft.dao.impl.DaoImpl"scope="prototype"> |
为什么bean默认为单例?
假设如果bean默认不是单例,那么我们新创建的bean会无穷无尽。
适合交给容器管理,只造一次就可以的bean
- 表现层对象
- 业务层对象
- 数据层对象
- 工具对象
不适合的
- 封装实体的域对象
bean实例化:
构造方法:
提供无参构造方法:
如果不存在无参构造方法,将会报错BeanCreationException(bean创建异常)
使用静态工厂实例化:
静态工厂:
public class DaoFoctory {
public static Dao getDao(){
return new DaoImpl();
}
}
配置:
<bean id="Daofoctory" class="com.jsoft.foctory.DaoFoctory" factory-method="getDao"></bean>
使用实例工厂实例化:
实例工厂:
public class DaoFoctory {
public Dao getDao(){
return new DaoImpl();
}
}
配置:
先配置工厂
<bean id="DaoFactory" class="com.jsoft.foctory.DaoFoctory" ></bean>
再配置方法,factory-bean必须指向工厂bean
<bean id="Dao" factory-method="getDao" factory-bean="DaoFactory"></bean>
上述方法,非常麻烦,配置工厂的bean完全为了配置而配置,没有实质的作用。所以进行了改良。
使用FoctoryBean实例化:
创建FoctoryBean类
public class DaoFoctoryBean implements FactoryBean<Dao> {
@Override
//代替原始实例工厂中创建对象的方法
public Dao getObject() throws Exception {
return new DaoImpl();
}
@Override
public Class<?> getObjectType() {
return Dao.class;
}
}
配置:
<bean id="Dao" class="com.jsoft.foctory.DaoFoctoryBean"></bean>
bean的生命周期:
bean的生命周期:从创建到消亡的过程
bean的生命周期控制:bean从创建到销毁这一过程做的一些事情
提供生命周期控制方法:
public class DaoImpl implements Dao {
@Override
public void MethodDao() {
System.out.println("Dao方法执行了");
}
//表示bean初始化对应的操作
public void init(){
System.out.println("init执行了");
}
//表示bean销毁前对应的操作
public void destory(){
System.out.println("destory执行了");
}
}
配置生命周期控制方法:
<bean id="Dao" class="com.jsoft.dao.impl.DaoImpl" init-method="init" destroy-method="destory"></bean>
或者我们可以使用接口:
public class ServiceImpl implements Service , InitializingBean, DisposableBean {
@Override
public void MethodService() {
System.out.println("Service方法执行了");
}
@Override
public void destroy() throws Exception {
System.out.println("destory");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
}
- 初始化对象
- 创建对象(分配内存)
- 执行构造方法
- 执行属性输入(set操作)
- 执行bean初始化方法
- 使用bean
- 执行业务操作
- 关闭销毁容器
- 执行bean销毁方法
bean的销毁
在容器关闭时,销毁bean
关闭容器方式
1.手动关闭容器
ConfigurableApplicationContext接口close()操作
applicationContext.close();
2.注册关闭钩子,在虚拟机推出前关闭
ConfigurableApplicationContext接口registerShutdownHook()操作
applicationContext.registerShutdownHook();
Spring的setter注入:
引用数据类型:
在bean中定义引用类型属性并提供set方法
public class ServiceImpl implements Service {
private Dao dao ;
public void setDao(Dao dao) {
this.dao = dao;
}
}
使用properties标签ref属性注入引用数据类型对象
<bean id="Dao" class="com.jsoft.dao.impl.DaoImpl"></bean>
<bean id="service" class="com.jsoft.service.impl.ServiceImpl">
<property name="dao(类里的变量名)" ref="Dao(配置文件的id)"></property>
</bean>
简单类型
在bean中定义类型类型并提供可使用的set方法
public class DaoImpl implements Dao {
private String words;
public void setWords(String words) {
this.words = words;
}
}
在配置文件中使用propertis标签value属性注入简单类型数据
<bean id="Dao" class="com.jsoft.dao.impl.DaoImpl">
<property name="words" value="我叫高牛逼"></property>
</bean>
依赖注入
构造器注入:
在bean中定义引用属性并提供可访问的构造方法
public class ServiceImpl implements Service {
private Dao dao;
public ServiceImpl(Dao dao) {
this.dao = dao;
}
}
配置中使用consturctor-arg标签ref属性注入引用标签
<bean id="service" class="com.jsoft.service.impl.ServiceImpl">
<constructor-arg name="dao" ref="Dao"></constructor-arg>
</bean>
简单类型注入:
在bean中定义简单类型数据,并提供构造器
public class DaoImpl implements Dao {
private String words;
public DaoImpl(String words){
this.words = words;
}
}
配置中使用constructor-arg标签value属性注入
<bean id="Dao" class="com.jsoft.dao.impl.DaoImpl">
<constructor-arg name="words" value="我叫高牛逼"></constructor-arg>
</bean>
参数适配:
如果有多个参数:
-
使用参数名字:
<bean id="service" class="com.jsoft.service.impl.ServiceImpl"> <constructor-arg name="dao" ref="Dao"></constructor-arg> <constructor-arg name="dao1" ref="Dao"></constructor-arg> </bean>
-
使用参数类型:
<bean id="service" class="com.jsoft.service.impl.ServiceImpl"> <constructor-arg type="com.jsoft.dao.Dao" ref="Dao"></constructor-arg> <constructor-arg type="int" value="10"></constructor-arg> </bean>
-
使用参数位置的下标:
<bean id="service" class="com.jsoft.service.impl.ServiceImpl"> <constructor-arg index="0" ref="Dao"></constructor-arg> <constructor-arg index="1" value="10"></constructor-arg> </bean>
依赖注入的原则:
- 强制依赖使用构造器进行
- 自己开发的模块推荐使用setter注入
依赖自动注入
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
依赖自动装配的方式:
- 按类型
- 按名称
- 按构造方法
- 不启动自动装配
数据源对象管理:
导入druid坐标:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.12</version>
</dependency>
配置数据源作为spring管理的bean
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Diver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jsoft"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
<property name="maxPoolSize" value="1000"/>
</bean>
使用注解管理对象:
使用@component定义bean
@Component("Dao")
public class DaoImpl implements Dao {}
@Component
public class ServiceImpl implements Service {}
在核心配置文件中通过组件扫描加载bean
<context:component-scan base-package="com.jsoft"/>
纯注解开发:
新建一个config包,在包里新建SpringConfig类
@Configuration
@ComponentScan("com.jsoft")
public class SpringConfig {
}
文件注解类也需要改变:
ClassPathXmlApplicationContext ---> AnnotationConfigApplicationContext
bean的作用范围:
@Scope定义bean的作用范围
@Scope("Singleton")单例
构造器运行之后
@PostConstruct
public void init(){
system.out.println( "book init ...");
}
销毁之前
@Predestory
public void destory(){
system.out.println("book destory")
}
依赖注入:
@Autowired
注意∶自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法
注意∶自动装配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法,请提供唯一的构造方法
如果想要指定加载某一个bean,使用
@Qualifier
具体实现
@Service
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier( "bookDao" )
private BookDao bookDao;
}
注意:@Qualifier注解无法单独使用,必须配合@Autowired注解使用
简单类型:
使用@value实现简单类型注入
@Repository( "bookDao")
public class BookDaoImpl implements BookDao {
@Value( "100")
private String connectionNum;
}
加载properties文件
使用@PropertySource注解加载properties文件
@Configuration
@ComponentScan( "com.itheima" )@PropertySource( "classpath:jdbc.properties " )
public class SpringConfig {
}
注意∶路径仅支持单一文件配置,多文件请使用数组格式配置,不允许使用通配符*
第三方bean管理:
使用@bean配置第三方bean
@Configuration
public class SpringConfig {
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource( );
ds.setDriverclassName( " com.mysql.jdbc.Driver"
ds.setUr1("jdbc:mysql: / / localhost: 3306/spring_db" );
ds.setUsername( "root" );
ds.setPassword( "root" );
return ds;
}
}
如果需要导入多个第三方bean
方式一:导入式(不建议这样做)
public class JdbcConfig {
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource()
//相关配置
return ds;
}
}
方式二:使用@Import注解手动加入配置类到核心配置,此注解只能添加一次,多个数据请用数组格式
@Configuration
@1mport(JdbcConfig.class)
public class SpringConfig {}
第三方bean依赖注入:
简单类型依赖注入
public class JdbcConfig {
@value( " com. mysql.jdbc.Driver")
private String driver;
@Value( "jdbc :mysql:/ /localhost: 3306/spring_db")
private String url;
private String userName;
@Value( "root" )
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName( driver);
ds.setUrl(url);
ds.setUsername( userName ) ;
ds. setPassword(userName ) ;
return ds;
}
}
引用类型依赖注入:
@Bean
public DataSource dataSource(BookService bookService){
system.out.println(bookService);
DruidDataSource ds = new DruidDataSource();
//属性设置
return ds;
}
}
引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】