spring核心理解

spring和spring boot、springcloud等的关联和区别

  • spring.io
  • Spring基础部分(IoC、DI、AOP)
  • spring boot:更加简单
    自动配置
    起步依赖(maven依赖更加简洁)
    领配置文件(spring配置文件)
  • spring framework(就是我们要学习的spring,这里面包含springmvc模块)
    分成很多组件(jar包)
  • Spring企业应用组件
    *** spring cloud
    *** spring data
    *** spring security
  • spring立志要成为一站式轻量级企业开发框架。

spring 核心概念

  • IoC:控制反转,其实new对象的权利由使用者改为spring去创建。spring要想使用IoC去创建对象,必须使用到DI
  • DI:依赖注入,就是给new出来的对象设置成员变量。
  • AOP:就是将项目中的业务代码(提交订单)和系统代码(事务、记录日志)进行解耦,也是给业务代码进行功能增强的一种途径。
  • AOP是和OOP一样,都是编程思想
  • AOP的实现都有哪些呢?
    spring aop
    AspectJ
    spring 整合 AspectJ
  • BOP:面向Bean的编程。在spring中一切都是针对Bean设计和编程的。
  • Bean被spring通过IoC和DI进行创建和管理。
  • Bean被spring通过AOP进行功能增强。
  • Bean其实就是对应bean标签和@Bean注解的类
  • 基础容器:IoC容器、【BeanFactory接口】(DefaultListableBeanFactory)
  • 高级容器:【ApplicationContext接口】,实现了BeanFactory接口,只是在该接口之外,新加了一些高级功能,本质是还是一个BeanFactory。
  • 高级容器和基础容器的区别
  • 高级容器对于bean实例的加载时机是项目启动时。(饿汉式加载)
  • 基础容器对于bean实例的加载时机是第一次被需要时。(懒汉式加载)
  • 循环依赖(A—>B … B—>A)
    构造方法的循环(无法解决)
public A{ 
	private B b;
	public A(B b){
	this.b = b;
	}
}
					
public B{ 
	private A a;
	public B(A a){
	this.a = a;
	}
}
  • set方法的循环(spring中可以通过缓存去解决掉)
public A{ 
	private B b;
	public setB(B b){
	this.b = b;
	}
}
					
public B{ 
	private A a;
	public setA(A a){
	this.a = a;
	}
}
  • spring中使用简单工厂模式去管理bean的分析
public BeanFactory{
	public Object getBean(String name){
		if ("cat".equals(name)) {
			return new Cat();
		} else if ("dog".equals(name)) {
			return new Dog();
		} else if ("cow".equals(name)) {
			return new Dog();
		} else {
			return null;
		}
	}
}			
//进化版-------------------------------------------------			
public BeanFactory{
	private Map map;
				
	public void init(){
		map.put("cat",new Cat());
		map.put("cow",new Cow());
	}
				
	public Object getBean(String name){
		return map.get(name);
	}
}
					
//Bean文件配置升级----------------------------------------------
public BeanFactory{
	private Map map;
				
	public void init(){
	//读取配置文件,获取bean的信息
	}
				
public Object getBean(String name){
	return map.get(name);
	}
}
<beans>
	<bean id="student" class="com.kkb.spring.po.Student">
		<!-- String类型 -->
		<property name="name" value="james"></property>
		<!-- 引用类型 -->
		<property name="course" ref="course"></property>
	</bean>

	<!-- 该类有一个初始化方法 -->
	<bean id="course" class="com.kkb.spring.po.Course"
		init-method="init">
		<!-- String类型 -->
		<property name="name" value="spring"></property>
		<!-- Integer类型 -->
		<property name="age" value="18"></property>
	</bean>
</beans>

通过画图搞清楚spring是如何通过容器去创建和管理bean实例的

hutool里的springContext_User


hutool里的springContext_spring_02

手写IOC模块

要求编写业务层、持久层以及使用数据源去获取连接

UserDao
UserDaoImpl
UserService
UserServiceImpl
User
BasicDataSource

代码

UserDao 接口代码

public interface UserDao {

	List<User> queryUserList(String sqlId, Object param);
}

UserDaoimpl 类 实现UserDao接口

public class UserDaoImpl2 implements UserDao {

	private DataSource dataSource;

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	@Override
	public List<User> queryUserList(String sqlId, Object param) {
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		ResultSet rs = null;

		try {
			connection = dataSource.getConnection();
			// 定义sql语句 ?表示占位符
			String sql = "select * from user where username = ?";

			System.out.println("SQL:" + sql);
			System.out.println("参数:" + param);
			// 获取预处理 statement
			preparedStatement = connection.prepareStatement(sql);
			User user = (User) param;
			preparedStatement.setObject(1, user.getUsername());
			// 向数据库发出 sql 执行查询,查询出结果集
			rs = preparedStatement.executeQuery();

			// 遍历查询结果集
			List<User> results = new ArrayList<User>();

			Class<?> clazz = User.class;
			while (rs.next()) {
				User instance = (User) clazz.newInstance();
				ResultSetMetaData metaData = rs.getMetaData();
				int columnCount = metaData.getColumnCount();
				for (int i = 0; i < columnCount; i++) {
					String columnName = metaData.getColumnName(i + 1);

					Field field = clazz.getDeclaredField(columnName);
					field.setAccessible(true);

					field.set(instance, rs.getObject(i + 1));
				}

				results.add(instance);
			}

			return results;
		} catch (

		Exception e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (preparedStatement != null) {
				try {
					preparedStatement.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block e.printStackTrace();
				}
			}
		}

		return null;
	}
}

UserService 接口

public interface UserService {

	List<User> queryUsers(User user);
}

UserServiceImpl 实现UserService 接口

public class UserServiceImpl implements UserService {

	private UserDao userDao;

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public List<User> queryUsers(User user) {
		return userDao.queryUserList("queryUserById",user);
	}
}

User 类

public class User {
	private int id;
	private String username;
	private Date birthday;
	private String sex;
	private String address;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", birthday=" + birthday + ", sex=" + sex + ", address="
				+ address + "]";
	}	
}

Test 类

public void test() throws Exception {
		UserServiceImpl service = new UserServiceImpl();
		UserDaoImpl2 userDao = new UserDaoImpl2();
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://XXX");
		dataSource.setUsername("XXX");
		dataSource.setPassword("XXX");
		
		userDao.setDataSource(dataSource);
		service.setUserDao(userDao);
		// 调用UserService的方法
		User user = new User();
		user.setUsername("王五");
		List<User> users = service.queryUsers(user);

		System.out.println("结果:" + users);
	}
}