0x00前言
spring框架应用的是ioc模式,ioc模式是指控制反转模式,本质是你不去创建对象让spring框架给你创建对象你去使用对象。多种开发模式通过配置文件和注解的方式去开发的都很值得去学习
0x01基础使用
构造一个接口
public interface userdo {
void select();
}
package spring;
public class mssqldaodimpl implements userdo{
@Override
public void select() {
System.out.println(\"mssqlselect\");
}
}
public class mysqldaoimpl implements userdo{
@Override
public void select() {
System.out.println(\"mysqldaoimp\");
}
}
如果按照平时开发的思路这个时候会去写一个test类去创建mssqldaodimpl、mysqldaoimpl去构建对象然后去执行两个的select方法
如果是在spring里面就会用ioc这种方式,这两个类都是ioc容器里面的两个bean只需要通过spring的模式去访问他们
先写配置文件
<?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=\"mysqldaoimpl\" class=\"spring.mysqldaoimpl\"/>
<bean id=\"mssqldaoimpl\" class=\"spring.mssqldaodimpl\"/>
</beans>
id是你用来寻找bean的名字,后面是更上的类
测试类
package spring;
import spring.userdo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(\"bean.xml\");
userdo mysqldoimpl = (userdo) context.getBean(\"mssqldaoimpl\");
userdo mysqldaoimpl = (userdo) context.getBean(\"mysqldaoimpl\");
mysqldaoimpl.select();
mysqldoimpl.select();
}
}
依赖注入
bean对象是被ioc容器所创造的,bean对象里面的属性也可以由ioc容器来构造
构造注入
构造注入:顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置
的方式,让 spring 框架来为我们注入参数
先构造一个实体类
package spring;
import java.util.Date;
public class People {
private String name;
private Integer age;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
private Date date;
public People(){
}
@Override
public String toString() {
return \"People{\" +
\"name=\'\" + name + \'\\\'\' +
\", age=\" + age +
\", date=\" + date +
\'}\';
}
public People(String name, Integer age, Date date) {
this.name = name;
this.age = age;
this.date=date;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
配置文件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=\"mysqldaoimpl\" class=\"spring.mysqldaoimpl\"/>
<bean id=\"mssqldaoimpl\" class=\"spring.mssqldaodimpl\"/>
<bean id=\"People\" class=\"spring.People\">
<constructor-arg name=\"name\" value=\"xiaohu\"/>
<constructor-arg name=\"age\" value=\"12\"/>
<constructor-arg name=\"date\" ref=\"now\"/>
</bean>
<bean id=\"People2\" class=\"spring.People\">
<property name=\"date\" ref=\"now\"></property>
</bean>
<bean id=\"now\" class=\"java.util.Date\"/>
</beans>
Set注入
<bean id=\"People\" class=\"spring.People\">
<constructor-arg name=\"name\" value=\"xiaohu\"/>//值可以直接通过value来赋值
<constructor-arg name=\"age\" value=\"12\"/>
<constructor-arg name=\"date\" ref=\"now\"/>//如果值是一个类可以用ref加一个新的bean对象来完成
</bean>
<bean id=\"now\" class=\"java.util.Date\"/>
name:找的是类中 set 方法后面的部分
ref:给属性赋值是其他 bean 类型的
value:给属性赋值是基本数据类型和 string 类型的
实际开发中,此种方式用的较多。
Bean标签的作用
作用:
用于配置对象让 spring 来创建的。
默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。
属性:
id: 给对象在容器中提供一个唯一标识。用于获取对象。
class: 指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
value: 用constructor-arg指定实例对象的具体属性。
*scope: 指定对象的作用范围。
* singleton :默认值,单例的.
* prototype :多例的.
* request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
* session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
* global session :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么
*globalSession 相当于 session.
*init-method: 指定类中的初始化方法名称。
*destroy-method: 指定类中销毁方法名称。
constructor-arg标签
index:指定参数在构造函数参数列表的索引位置
type:指定参数在构造函数中的数据类型
name:指定参数在构造函数中的名称
value:它能赋的值是基本数据类型和 String 类型
ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
自动装配
在spring框架里面可以自动装配Bean。我们只需要在bean标签里面加上 autowire就可以了。
autowire属性:
先看源码:
per类
package spring.auto_bean;
public class per {
private String name;
private Dog dog;
private Cat cat;
public per(String name, Dog dog, Cat cat) {
this.name = name;
this.dog = dog;
this.cat = cat;
}
public per() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
@Override
public String toString() {
return \"per{\" +
\"name=\'\" + name + \'\\\'\' +
\", dog=\" + dog +
\", cat=\" + cat +
\'}\';
}
}
dog和cat类
package spring.auto_bean;
public class Dog {
public void method(){
System.out.println(\"dog\");
}
}
看一下怎么配置自动装配的
<?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=\"per\" class=\"spring.auto_bean.per\" autowire=\"byType\">
<property name=\"name\" value=\"xiaoming\"/>
</bean>
<bean id=\"cat\" class=\"spring.auto_bean.Cat\"/>
<bean id=\"dog\" class=\"spring.auto_bean.Dog\"/>
</beans>
看一下标签内容
no :缺省情况下,自动配置是通过“ref”属性手动设定
byName:根据属性名称自动装配。如果一个bean的名称和其他bean属性的名称是一样的,将会自装配它。
byType:按数据类型自动装配。如果一个bean的数据类型是用其它bean属性的数据类型,兼容并自动装配它。
constructor:在构造函数参数的byType方式。
autodetect:如果找到默认的构造函数,使用\"自动装配用构造\"否则,使用“按类型自动装配
简单理解一下这个标签如果我此时配置文件是,我选用的是通过名字自动装配,我在per类里面写的是小写的cat
在这里的bean id写的是大写的,他输出的结果是:per{name=\'xiaoming\', dog=spring.auto_bean.Dog@4a94ee4, cat=null},cat为空没有装配到
<?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=\"per\" class=\"spring.auto_bean.per\" autowire=\"byName\">
<property name=\"name\" value=\"xiaoming\"/>
</bean>
<bean id=\"Cat\" class=\"spring.auto_bean.Cat\"/>
<bean id=\"dog\" class=\"spring.auto_bean.Dog\"/>
</beans>
如果我使用byType结果是:per{name=\'xiaoming\', dog=spring.auto_bean.Dog@6d763516, cat=spring.auto_bean.Cat@52bf72b5}
Cat被识别到因为用的是class去识别的
集合注入
直接通过配置文件的方式完成
<?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\">
<!-- 还是采用set注入-->
<bean id=\"arrlist\" class=\"spring.auto_bean.per\">
<property name=\"cat\">
<array>
<value>100</value>
<value>100</value>
</array>
</property>
</bean>
<bean id=\"map\" class=\"spring.auto_bean.per\">
<property name=\"name\">
<map><entry key=\"name\" value=\"HELLO\"></entry> </map>
</property>
</bean>
</beans>
各种数据类型对应不同的格式,只需要简单的了解一下就OK
注解自动装配
如果使用注解自动装载bean的话,我们需要对xml进行一个配置,加上context:annotation-config标签,并且需要导入约束。
<?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
https://www.springframework.org/schema/context/spring-context.xsd\">
<context:annotation-config/>
<bean id=\"cat\" class=\"spring.auto_bean.Cat\"/>
<bean id=\"dog\" class=\"spring.auto_bean.Cat\"/>
<bean id=\"person\" class=\"spring.auto_bean.per\">
<property name=\"name\" value=\"xiaoming\"/>
</bean>
</beans>
然后在类上面写上注解标签@Autowired
0x02注解开发配置
0x1容器
容器获取方式1:通过了路径活得xml配置文件
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(\"bean2.xml\");
配置方式2:通过文件路径获取配置文件
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(\"D://bean2.xml\");
BeanFactory是IOC顶层的接口,初始化BeanFactory对象时,加载bean延迟加载
AppLicationContext接口是Spring容器的核心接口,初始化Bean的时候立即加载
ApplicationContext常用的初始化分类
常用的类:ClassPathXmlApplicationContext
FileSystemApplicationContext
0x2注解开发自定义bean
先写一个主类
package spring.editbean;
import org.springframework.stereotype.Component;
@Component(\"Animal\")
public class Anmial {
private chicken chicken;
private duke duke;
public spring.editbean.chicken getChicken() {
return chicken;
}
public void setChicken(spring.editbean.chicken chicken) {
this.chicken = chicken;
}
public spring.editbean.duke getDuke() {
return duke;
}
public void setDuke(spring.editbean.duke duke) {
this.duke = duke;
}
public Anmial(spring.editbean.chicken chicken, spring.editbean.duke duke) {
this.chicken = chicken;
this.duke = duke;
}
@Override
public String toString() {
return \"Anmial{\" +
\"chicken=\" + chicken +
\", duke=\" + duke +
\'}\';
}
}
和两个分类
package spring.editbean;
import org.springframework.stereotype.Component;
@Component(\"duke\")
public class duke {
public void method(){
System.out.println(\"duke被执行了\");
}
public duke() {
System.out.println(\"duke的构造函数被执行了\");
}
}
在你需要自定义的类上面加上@Component(\"duke\"):意思就是定义一个组件然后给他的名字是,然后在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\"
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 https://www.springframework.org/schema/context/spring-context.xsd\">
<context:component-scan base-package=\"spring\"/>
</beans>
<context:component-scan base-package=\"spring\"/>
去spring包下搜索组件。
步骤:
-
在类上面创建注释
-
如果类有其他引用数据类型需要在其他引用数据类型上面也要加注释
-
在xml文件中配置自动搜索和搜索路径
测试代码
public class TEST {
public static void main(String[] args) {
ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(\"bean5.xml\");
Anmial anmial = (Anmial) classPathXmlApplicationContext.getBean(\"Animal\");
System.out.println(anmial);
}
}
输出结果:Anmial{chicken=spring.editbean.chicken@62230c58, duke=spring.editbean.duke@2cd2a21f}+两个分类的构造函数结果。
bean注解配置的三个分支
@Controller 用于表现层的注解bean
@Service 用于业务层bean注解
@Repository 用于数据层的bean定义
0x3bean生命周期和作用范围
@Scope定义作用范围
@PostConstruct构造方法前执行
@PreDestroy销毁方法前执行
0x4纯注解开发
把配置文件改成配置类
@Configuration
@ComponentScan(\"spring\")
@PropertySource(\"value.properties\")
public class springconfig {
}
@Configuration确定为配置类
@ComponentScan(\"去扫描包,找到bean\")
@PropertySource(\"value.properties\")对value的配置文件的的配置用键值对的方式存在。
自动配置
@Component(\"Animal\")
public class Anmial {
@Autowired
private chicken chicken;
@Autowired
private duke duke;
@Value(\"${name}\")
private String name;
- Value的值就是通过前面传入的文件导入的
0x5管理三方Bean
用到的方法是用写配置类的方法,然后通过Bean去构造一个bean
@Configuration
//定义一个方法去管理对象
public class mangerbean {
@Bean
public DataSource dataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(\"com.mysql.jdbc.Drvier\");
druidDataSource.setUrl(\"jdbc:mysql://localhost:3306/tese\");
druidDataSource.setUsername(\"root\");
druidDataSource.setPassword(\"zhonglin\");
return druidDataSource;
}
}
测试方法
@Test
public void manger(){
ApplicationContext acac = new AnnotationConfigApplicationContext(mangerbean.class);
DataSource bean = acac.getBean(DataSource.class);
System.out.println(bean);
}
}
0X03结尾
ioc模型很重要这种bean注入的形式不去自己创造对象的思路很重要,各种重要的标签可以做完为以后形成构造链分析的好帮手,同时现在也正式开始恢复正常的学习
来源:https://www.cnblogs.com/0x3e-time/p/16420996.html
本站部分图文来源于网络,如有侵权请联系删除。