简介
最近学习了很多框架的知识,spring,springmvc,mybatis等等,这些框架让我感受到便利的同时也让我感受到了需要记忆了解的内容的量很大,很快的接触很多框架有点应接不暇,所以想总结一下框架的使用要点
知识点回顾
1.通过IOC实现对对象的管控
1.1 IOC使用步骤
1.引入jar包,通过maven引入对应依赖实现。
IOC实现需要的包的groupId都是org.springframework
具体需要的包的artifactId如下所示:
- spring-core(Spring的核心工具包)
- spring-context(在基础IOC功能上提供扩展服务)
- spring-beans( Spring IOC的基础实现,包含访问配置文件、创建和管理bean等)
- spring-context-support(Spring context的扩展支持,用于MVC方面)
- spring-expression(Spring表达式语言)
2.创建对应的配置文件application.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">
</beans>
3.在配置文件中创建对象
按照下图的形式创建
<bean id="对象名" class="类的完整路径">
<property name="属性名" ref="对象的id值"></property>
</bean>
注意:通过容器给属性赋值时 默认通过set方法赋值
4.在对应的使用类中加载配置文件使用对象
ApplicationContext app=new ClassPathXmlApplicationContext("spring.xml");
Users users=(Users)app.getBean("u1");
第一步加载配置文件,第二步通过getBean获得对应的对象
对应错误总结:
-
如果没有set方法就让容器赋值:
图中出现提示:无法解析属性usersDao,给出的首要解决办法也是生成一个set方法。 -
xml文件名称不正确
将名称大小写随意更改之后,文件仍然能够正常识别,此时我就有了一个想法,如果出现了对应大小写的文件他是如何读取文件的呢?
结果我发现无法创建一个大小写不同的xml文件… -
对象名称错误:
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="dao" class="com.trx.dao.impl.UsersDaoImpl">
</bean>
<bean id="uservice" class="com.trx.service.impl.UsersServiceImpl">
<property name="usersDao" ref="dao"></property>
</bean>
</beans>
执行代码:
public class Test1 {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("ApPliCation.xml");
UsersService uservice =(UsersServiceImpl) app.getBean("Uservice");
uservice.test1();
}
}
如果出现名称改换大小写或者名称不存在时会出现如下错误提示
1.2 bean标签的属性介绍
我们发现xml文件中的bean标签是管控对象的关键,接下来会熟悉bean标签的内容以及如何使用:
- scope管控重复创建的对象是否为同一个,如果是singleton,则所有对应id的对象为同一个,如果是prototype那么对应id创造出的对象各不相同
- lazy-init为true是不调用对象就不创建对象,默认时为false,就算不调用对象,会将xml中所有对象都创建一次
1.3 对象创建的方式
方式一共有4种:
- 无参构造方式
<bean id="u1" class="com.trx.bean.Users"></bean>
- 有参构造方式
<bean id="u2" class="com.trx.bean.Users">
<constructor-arg index="0" value="xioaming"></constructor-arg>
<constructor-arg index="1" value="12"></constructor-arg>
</bean>
- 静态工厂模式
<bean name="c1" class="com.trx.bean.Users" factory-method="getCarStatic"></bean>
- 非静态工厂方法
<bean id="u3" class="com.trx.bean.Users"></bean>
<bean id="c2" factory-method="getCar" factory-bean="u3"></bean>
上面代码中使用的构造对象:
public class Users {
public Users(){
System.out.println("无参Users创建");
}
private Car car;
private String name;
private int age;
private int className;
public Users(String name,int age){
System.out.println("create Users:name = " + name + " age = " + age);
}
public Users(String name,int age,Car car){
System.out.println("create Users:name = " + name + " age = " + age + " Car = " + car);
}
public static Car getCarStatic(){
System.out.println("static method get Car---");
return new Car();
}
public Car getCar(){
System.out.println("usual method get Car---");
return new Car();
}
}
注意点:
- 参数构造:
如果使用参数构造时,如果没有按照给出的构造方法构造对象,他会给出提示已有的构造方法有哪些。
1.4 springBean的生命周期
1.5 DI注入值
- set注入值
<bean id="service" class="com.trx.service.impl.UsersServiceImpl">
<property name="usersDao" ref="dao"></property>
</bean>
这种方法需要类中有对应属性的set方法
- 构造注入
根据name注入值:
<bean id="u2" class="com.trx.bean.Users">
<constructor-arg name="name" value="xioaming"></constructor-arg>
<constructor-arg name="age" value="12"></constructor-arg>
</bean>
根据下标注入值:
<bean id="u2" class="com.java.bean.Users">
<constructor-arg index="0" value="zhangsan" ></constructor-arg>
<constructor-arg index="1" value="18"></constructor-arg>
</bean>
- spel spring表达式
<bean id="stu1" class="com.java.bean.Student">
<property name="stuname" value="lisi"></property>
</bean>
<bean id="stu2" class="com.java.bean.Student">
<constructor-arg name="sex" value="男"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="stuname" value="#{stu1.stuname}"></constructor-arg>
</bean>
- p命名空间注入值
<bean id="stu3" class="com.java.bean.Student" p:age="18" p:sex="女" p:stuname="erersansan">
</bean>
如果是引用类型对象在等号之前加上-ref
- 复杂类型注入
对象代码:
public class Teacher {
private Object[] obj;
private List list;
private Set set;
private Map map;
private Properties properties;//属性类型
public Object[] getObj() {
return obj;
}
public void setObj(Object[] obj) {
this.obj = obj;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Set getSet() {
return set;
}
public void setSet(Set set) {
this.set = set;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "Teacher{" +
"obj=" + Arrays.toString(obj) +
", list=" + list +
", set=" + set +
", map=" + map +
", properties=" + properties +
'}';
}
}
注入代码:
<bean id="u1" class="com.java.bean.Users"></bean>
<bean id="t1" class="com.java.bean.Teacher">
<property name="obj">
<list>
<value>张三1</value>
<value>zhangsan2</value>
<value>zhangsan3</value>
<ref bean="u1"></ref>
</list>
</property>
<property name="list">
<list>
<value>张三2</value>
<value>zhangsan22</value>
<value>zhangsan33</value>
<ref bean="u1"></ref>
</list>
</property>
<property name="set">
<set>
<value>张三3</value>
<value>zhangsan222</value>
<value>zhangsan333</value>
<ref bean="u1"></ref>
</set>
</property>
<property name="map">
<map>
<entry key="班长" value="张三"></entry>
<entry key="班花" value="12131"></entry>
<entry key="user" value-ref="u1"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="username" >root</prop>
<prop key="code">123456</prop>
</props>
</property>
</bean>
- 自动注入
autowire:
- no 不自动装配(默认值)
- byName 属性名=id名 ,调取set方法赋值
- byType 属性的类型和id对象的类型相同,当找到多个同类型的对象时报错,调取set方法赋值
- constructor 构造方法的参数类型和id对象的类型相同,当没有找到时,报错。调取构造方法赋值
<bean id="usersDao" class="com.java.dao.impl.UsersDaoImpl"></bean>
<bean id="uservice" class="com.java.Service.impl.UsersServiceImpl" autowire="byName">
注意点:
1.如果同时使用p命名空间和构造注入
public class Test4 {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("application2.xml");
Object stu3 = app.getBean("stu3");
System.out.println(stu3);
}
}
最终属性值会变成p空间注入的值
2.引用类型自动注入 p空间注入 构造注入同时使用结果
public class UsersDaoImpl implements UsersDao {
@Override
public int insertUsers(Users users) {
System.out.println("insertUsers:UsersDaoImpl");
return 0;
}
}
public class UsersDaoImpl2 implements UsersDao {
@Override
public int insertUsers(Users users) {
System.out.println("insertUsers:UsersDaoImpl2");
return 0;
}
}
public class UsersDaoImpl3 implements UsersDao {
@Override
public int insertUsers(Users users) {
System.out.println("insertUsers:UsersDaoImpl3");
return 0;
}
}
public class Test6 {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationioc.xml");
UsersService uservice =(UsersService)app.getBean("uservice");
uservice.insertUsers(new Users());
}
}
如果三者同时写上去 最终剩下的是p空间的
如果将p空间的删除 最终剩下的是自动注入的