免费内容(初学,复习,和就业前,知识回顾)
Spring工厂模式的实现
学习中如果有想要了解的知识和不会的可以评论留言,尽最大可能帮助你们,也会把问题的答案免费发布出来供提问的和其他人参考
章语
世事多因忙中错,好人半自苦中来。
永远别放弃,哪怕所有人都放弃了你。 --恠咖
请认真仔细阅读发布的内容,有很多实战开发中的细节,很容易忽视掉
此文档连续更新中,所有框架内容以及微服务架构开发和实战项目
1,Spring概述以及第一个Spring(第一章)
2,Spring整合日志框架以及Spring核心控制反转依赖注入(第二章上内容多正在整理)
3,Spring整合日志框架以及Spring核心控制反转依赖注入(中)
4,Spring整合日志框架以及Spring核心控制反转依赖注入(下)(第四节)
下次更新
学完注入和对象创建,接下来就要进入复杂类型创建和源码刨析。还有一些零碎的只是,配置文件参数化,整合YML 自定义类型转换器,即将步入Spring第二个核心AOP以及原理分析,整合Mybatis和事务,使用注解开发
持续更新
复杂类型的注入
学完了简单类型的注入,下面来学习复杂类型的注入,也就是以对象作为属性值,也可以理解为在创建的类中再创建一个类代码演示
步骤
1. 实体类
2. DAO层
3. Service层
4. 配置文件
5. 测试类
步骤
实体类
public class User {
private String Username;
private String Password;
public String getUsername() {
return Username;
}
public void setUsername(String username) {
Username = username;
}
public String getPassword() {
return Password;
}
public void setPassword(String password) {
Password = password;
}
}
DAO层接口
import com.pojo.User;
public interface UserDAO {
//模拟插入数据
void Save(User user);
}
DAO层实现类
import com.pojo.User;
public class UserDAOImpl implements UserDAO {
public void Save(User user) {
System.out.println("insert into User(username,password) values('wang','0701')");
}
}
Service层接口
import com.pojo.User;
public interface UserService {
void Save(User user);
}
Service实现层
import com.dao.UserDAO;
import com.pojo.User;
public class UserServiceImpl implements UserService {
private UserDAO userDAO;
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public void Save(User user) {
userDAO.Save(user);
}
}
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="user" class="com.pojo.User"/>
<bean id="userService" class="com.service.UserServiceImpl">
<property name="userDAO" >
<bean class="com.dao.UserDAOImpl"/>
</property>
</bean>
</beans>
这里的属性值对应的是ServiceImpl里的
private UserDAO userDAO;
//可以理解为
UserDAO userDAO = new UserDAOImpl();
//将创建UserDAOImpl对象赋值给userDAO类型为UserDAO
配置文件
<property name="userDAO"></property> ==== private UserDAO userDAO
<bean class="com.dao.UserDAOImpl"/> 创建一个对象没有指定id 赋值给userDAO
测试类
import com.pojo.User;
import com.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserTest {
@Test
public void userTest(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("/ApplicationContext03.xml");
UserService userService = ctx.getBean("userService", UserService.class);
User user = ctx.getBean("user", User.class);
user.setUsername("admin");
user.setPassword("0701");
userService.Save(user);
}
}
运行结果
以上就是创建复杂类型的步骤,按照分层的方式简单的进行模拟整合Mybatis按照MVC的架构进行开发,后面也会有整合Mybatis ,等以及其他框架内容.
思考分析
这种注入属性有什么缺陷?
第一种赋值方式存在的问题
1. 配置文件代码冗余
2. 被注入的对象(UserDAO),多次创建,浪费(JVM)内存资源
<bean id="user" class="com.pojo.User"/>
<bean id="userService" class="com.service.UserServiceImpl">
<property name="userDAO" >
<bean class="com.dao.UserDAOImpl"/>
</property>
</bean>
第二种注入复杂类型的方式
其他代码不需要改变只需要修改配置文件即可
<bean id="userDAO" class="com.dao.UserDAOImpl"/>
<bean id="userService" class="com.service.UserServiceImpl">
<property name="userDAO">
<bean ref="userDAO"/>
</property>
</bean>
可以把创建的对象属性单独提取出来然后通过ref进行引用,这也是开发中常用的一种方法
也可以简化为
<bean id="userDAO" class="com.dao.UserDAOImpl"/>
<bean id="userService" class="com.service.UserServiceImpl">
<property name="userDAO" ref="userDAO"/>
</bean>
构造注入
1. Set注入:Spring调用Set方法,通过配置文件,为成员变量赋值
2. 构造注入:Spring调用构造方法,通过配置文件,为成员变量赋值
实体类
import java.util.List;
public class Constructor {
private String Username;
private int age;
private List<String> hobby;
public Constructor(String username, int age, List<String> hobby) {
Username = username;
this.age = age;
this.hobby = hobby;
}
public String getUsername() {
return Username;
}
public void setUsername(String username) {
Username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getHobby() {
return hobby;
}
public void setHobby(List<String> hobby) {
this.hobby = hobby;
}
@Override
public String toString() {
return "Constructor{" +
"Username='" + Username + '\'' +
", age=" + age +
", hobby=" + hobby +
'}';
}
}
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="constructor" class="com.jing.Constructor">
<constructor-arg name="username" value="admin"/>
<constructor-arg name="age" value="18"/>
<constructor-arg name="hobby">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</constructor-arg>
</bean>
</beans>
测试类
import com.jing.Constructor;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ConstructorTest {
//构造注入
@Test
public void Constructortest(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("/ApplicationContext04.xml");
Constructor constructor = ctx.getBean("constructor", Constructor.class);
System.out.println(constructor);
}
}
运行结果
对象注入
<bean id="userService" class="com.service.UserServiceImpl">
<constructor-arg ref="userDAO"/>
</bean>
构造注入的其他方式
根据index进行注入
以索引0开始
<bean id="constructor" class="com.jing.Constructor">
<constructor-arg index="0" value="admin"/>
<constructor-arg index="1" value="18"/>
<constructor-arg index="2">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</constructor-arg>
</bean>
根据数据类型进行注入
<bean id="constructor" class="com.jing.Constructor">
<constructor-arg type="java.lang.String" value="admin"/>
<constructor-arg type="int" value="18"/>
<constructor-arg type="java.util.List">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</constructor-arg>
</bean>
直接传值
直接给参数赋值,这种方法也是根据顺序排的,所以一旦调换位置的话,就会出现bug,这种方法已经很原始了,了解即可。
<bean id="constructor" class="com.jing.Constructor">
<constructor-arg value="admin"/>
<constructor-arg value="18"/>
<constructor-arg>
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</constructor-arg>
</bean>
以上就是构造注入的方法Set集合,Map集合和set注入写法如出一辙,可以自己进行练习,最好的学习方法就是坚持和复习.
注入总结
在实际开发中最常用的还是根据name进行注入,也是推荐的一种使用方法。
以下图用来展示如何选用注入方式
p命名空间和c命名空间
p命名空间和c命名空间
在通过构造方法或set方法给bean进行注入时,是通过constructor-arg元素和property元素来定义的,而p命名空间和c命名空间就是新的一种写法进行注入,功能上并没有什么区别,只是在写法上进行了简化,需要注意的是Spring的版本必须在3.1及以上
p命名空间
使用p命名空间时需要先声明使用对应的命名空间,即在beans元素上加入xmlns:p=“http://www.springframework.org/schema/p”,以下就是p命名空间的使用方法 格式:普通属性 p:属性名=”值” 对象属性 p:属性名-ref=”值”*,必要条件需要有set方法
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--原始的写法-->
<bean id="classic" class="com.pojo">
<property name="email" value="9685@qq.com"/>
</bean>
<!--使用p命名空间注入普通属性-->
<bean id="p-namespace" class="com.pojo" p:email="8544@qq.com"/>
<!--使用p命名空间注入对象属性-->
<bean id="userDAO" class="com.dao.UserDAOImpl"/>
<bean id="userService" class="com.service.UserServiceImpl" p:userDAO-ref="userDAO"/>
</beans>
需要注意的是p命名空间和c命名空间只使用于8种基本数据类型+String 和自定义类型
c命名空间
c命名空间在实现的功能上和p命名空间完全相同,唯一的区别就是p命名空间是通过set进行注入的而c命名空间则是通过构造方法注入的
格式:普通属性 c:属性名=”值” 对象属性 c:属性名-ref=”值”*,必要条件需要有构造方法其他与p命名空间的用法如出一辙。
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--原始的写法-->
<bean id="classic" class="com.pojo">
<property name="email" value="9685@qq.com"/>
</bean>
<!--使用c命名空间注入普通属性-->
<bean id="p-namespace" class="com.pojo" c:email="8544@qq.com"/>
<!--使用c命名空间注入对象属性-->
<bean id="userDAO" class="com.dao.UserDAOImpl"/>
<bean id="userService" class="com.service.UserServiceImpl" c:userDAO-ref="userDAO"/>
</beans>
复合属性
复合属性即嵌套属性可以理解为,为对象属性指定其属性值例:
<bean id="student" class="com.jing.Student" >
</bean>
<bean id="attribute" class="com.jing.Attribute">
<property name="student" ref="student"/>
<property name="student.name" value="小飞"/>
</bean>
如果嵌套的对象属性中还有属性的话还可以通过.(点)继续赋值 下面举个简单的完整的例子
步骤
1. 教师类
2. 学生类
3. 成绩类
4. 配置文件
教师类
public class Teacher{
private String tname;
public void setTeacher(String tname){
this.tname = tname;
}
public String getTeacher(){
return tname;
}
}
学生类
public class Student{
private String sname;
private Teacher teacher;
public void setStudent(String sname){
this.sname = sname;
}
public String getStudent(){
return sname;
}
}
成绩类
public class Score{
private int score;
private Student student;
public void setScore(int score){
this.score=score;
}
public int getScore(){
return score;
}
}
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="student" class="com.jing.Student"/>
<bean id="score" class="com.jing.Score">
<property name="score" value="95"/>
<property name="student" ref="student"/>
<property name="student.sname" value="小飞"/>
<property name="student.teacher.tname" value="李老师"/>
</bean>
</beans>
以上就是复合属性很少这样用,官方文档中也有一个例子不过描述的不是很清楚。