从Spring5之后,Spring框架支持集成的日志框架是Log4j2.如何启用日志框架:
第一步:引入Log4j2的依赖
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-coreartifactId>
<version>2.19.0version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-slf4j2-implartifactId>
<version>2.19.0version>
dependency>
第二步:在类的根路径下提供log4j2.xml配置文件(文件名固定为:log4j2.xml,文件必须放到类根路径下。)
<configuration>
<loggers>
<root level="DEBUG">
<appender-ref ref="spring6log"/>
root>
loggers>
<appenders>
<console name="spring6log" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/>
console>
appenders>
configuration>
第三步:使用日志框架
Logger logger = LoggerFactory.getLogger(FirstSpringTest.class);
logger.info("我是一条日志消息");
● 依赖指的是对象和对象之间的关联关系。
● 注入指的是一种数据传递行为,通过注入行为来让对象和对象产生关系。
依赖注入常见的实现方式包括两种:
● 第一种:set注入
● 第二种:构造注入
新建模块:spring6-003-dependency-injection
set注入,基于set方法实现的,底层会通过反射机制调用属性对应的set方法然后给属性赋值。这种方式要求属性必须对外提供set方法。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.powernodegroupId>
<artifactId>spring6-002-dependency-injectionartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>jarpackaging>
<repositories>
<repository>
<id>repository.spring.milestoneid>
<name>Spring Milestone Repositoryname>
<url>https://repo.spring.io/milestoneurl>
repository>
repositories>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>6.0.0-M2version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13.2version>
<scope>testscope>
dependency>
dependencies>
<properties>
<maven.compiler.source>17maven.compiler.source>
<maven.compiler.target>17maven.compiler.target>
properties>
project>
UserDao.java
package com.w.spring6.dao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserDao {
private static final Logger logger= LoggerFactory.getLogger(UserDao.class);
public void insert(){
//System.out.println("数据库正在保存信息");
logger.info("数据库正在保存信息");
}
}
UserService.java
package com.w.spring6.service;
import com.w.spring6.dao.UserDao;
import com.w.spring6.dao.VipDao;
public class UserService {
private UserDao userDao;
private VipDao vipDao;
public void setAbc(VipDao vipDao){
this.vipDao=vipDao;
}
//set注入的话,必须提供一个set方法
//spring容器会调用这个set方法,来给userDao赋值
/* //自己写的不符合javabean规范
public void setMySQLUserDao(UserDao xyz){
this.userDao=xyz;
}*/
//idea自动生成的符合javabean规范
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void saveUser(){
userDao.insert();
vipDao.insert();
}
}
spring.xml
<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="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>
<bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
<property name="userDao" ref="userDaoBean"/>
bean>
beans>
SpringDITest.java
package com.w.spring6.text;
import com.w.spring6.bean.QianDaYe;
import com.w.spring6.bean.User;
import com.w.spring6.jdbc.MyDataSource;
import com.w.spring6.service.CustomerService;
import com.w.spring6.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDITest {
@Test
public void testSetDI(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = applicationContext.getBean("userServiceBean", UserService.class);
userService.save();
}
}
实现原理:
通过property标签获取到属性名:userDao
通过属性名推断出set方法名:setUserDao
通过反射机制调用setUserDao()方法给属性赋值
property标签的name是属性名。
property标签的ref是要注入的bean对象的id。
总结:set注入的核心实现原理:通过反射机制调用set方法来给属性赋值,让两个对象之间产生关系。
之前注入对象属性为UserDao,当对象的属性是int类型时该怎么写
例:编写程序给一个User对象的age属性赋值20:
第一步:定义User类,提供age属性,提供age属性的setter方法。
package com.w.spring6.bean;
public class User {
private String username;
private String password;
private int age;
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
'}';
}
}
第二步:编写spring配置文件:beans.xml,添加
<bean id="userBean" class="com.w.spring6.bean.User">
<property name="username" value="张三"/>
<property name="password" value="123"/>
<property name="age" value="20"/>
bean>
注意:如果给简单类型赋值,使用value属性或value标签。而不是ref
第三步:编写测试程序
@Test
public void testSimpleTypeSet() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml");
User user=applicationContext.getBean("userBean", User.class);
System.out.println(user);
}
自己手写一个数据源,所有的数据源都要实现javax.sql.DataSource接口,并且数据源中应该有连接数据库的信息,例如:driver、url、username、password等。
第一步:新建MyDataSource.java,提供4个属性,并提供setter方法。
package com.w.spring6.jdbc;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
/*
所有的数据源都要实现java规范:java.sql.DataSource
什么是数据源:能够给你提供Connection对象的,都是数据源
*/
public class MyDataSource implements DataSource { //可以把数据源给spring容器管理
private String driver;
private String url;
private String username;
private String password;
@Override
public String toString() {
return "MyDataSource{" +
"driver='" + driver + '\'' +
", url='" + url + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
public void setDriver(String driver) {
this.driver = driver;
}
public void setUrl(String url) {
this.url = url;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public Connection getConnection() throws SQLException {
return null;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
}
第二步:编写spring配置文件:spring-properties.xml,我们给driver、url、username、password四个属性分别提供了setter方法,我们可以使用spring的依赖注入完成数据源对象的创建和属性的赋值
<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 http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="jdbc.properties"/>
<bean id="dataSource" class="com.w.spring6.jdbc.MyDataSource">
<property name="driver" value="${jdbc.driverClass}">property>
<property name="url" value="${jdbc.url}">property>
<property name="username" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
bean>
beans>
第三步:编写测试程序
@Test
public void testProperties() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-properties.xml");
MyDataSource da=applicationContext.getBean("dataSource", MyDataSource.class);
System.out.println(da);
}
当数组中的元素是简单类型和不是简单类型
QianDaYe.java
package com.w.spring6.bean;
import java.util.Arrays;
public class QianDaYe {
private String[] aiHaos;
private Woman[] womens;
@Override
public String toString() {
return "QianDaYe{" +
"aiHaos=" + Arrays.toString(aiHaos) +
", womens=" + Arrays.toString(womens) +
'}';
}
public void setWomens(Woman[] womens) {
this.womens = womens;
}
public void setAiHaos(String[] aiHaos) {
this.aiHaos = aiHaos;
}
}
Woman.java
package com.w.spring6.bean;
public class Woman {
private String name;
@Override
public String toString() {
return "Woman{" +
"name='" + name + '\'' +
'}';
}
public void setName(String name) {
this.name = name;
}
}
spring-array.xml
<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="w1" class="com.w.spring6.bean.Woman">
<property name="name" value="小花"/>
bean>
<bean id="w2" class="com.w.spring6.bean.Woman">
<property name="name" value="小红"/>
bean>
<bean id="w3" class="com.w.spring6.bean.Woman">
<property name="name" value="小丽"/>
bean>
<bean id="yuQian" class="com.w.spring6.bean.QianDaYe">
<property name="aiHaos">
<array>
<value>抽烟value>
<value>喝酒value>
<value>打麻将value>
array>
property>
<property name="womens">
<array>
<ref bean="w1"/>
<ref bean="w2"/>
<ref bean="w3"/>
array>
property>
bean>
beans>
SpringDITest.java
@Test
public void testArray() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-array.xml");
QianDaYe yuQian=applicationContext.getBean("yuQian", QianDaYe.class);
System.out.println(yuQian);
}
List集合:有序可重复
注意:注入List集合的时候使用list标签,如果List集合中是简单类型使用value标签,反之使用ref标签
People.java
package com.w.spring6.bean;
import java.util.List;
public class People {
// 一个人有多个名字
private List<String> names;
public void setNames(List<String> names) {
this.names = names;
}
@Override
public String toString() {
return "People{" +
"names=" + names +
'}';
}
}
spring-collection.xml
<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="peopleBean" class="com.w.spring6.bean.People">
<property name="names">
<list>
<value>铁锤value>
<value>张三value>
<value>张三value>
<value>张三value>
<value>狼value>
list>
property>
bean>
beans>
测试程序:
@Test
public void testCollection(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-collection.xml");
People peopleBean = applicationContext.getBean("peopleBean", People.class);
System.out.println(peopleBean);
}
之后的Set集合和Map集合同理,就不演示了
<set>
<value>110value>
<value>120value>
<value>119value>
set>
<map>
<entry key="1" value="北京"/>
<entry key="2" value="上海"/>
<entry key="3" value="深圳"/>
map>
核心原理:通过调用构造方法来给属性赋值。
OrderDao
package com.w.spring6.dao;
public class OrderDao {
public void deleteById(){
System.out.println("正在删除订单。。。");
}
}
OrderService
package com.w.spring6.service;
import com.w.spring6.dao.OrderDao;
public class OrderService {
private OrderDao orderDao;
// 通过反射机制调用构造方法给属性赋值
public OrderService(OrderDao orderDao) {
this.orderDao = orderDao;
}
public void delete(){
orderDao.deleteById();
}
}
spring.xml添加
<bean id="orderDaoBean" class="com.w.spring6.dao.OrderDao"/>
<bean id="orderServiceBean" class="com.w.spring6.service.OrderService">
<constructor-arg index="0" ref="orderDaoBean"/>
bean>
测试程序:
SpringDITest.java
@Test
public void testConstructorDI(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
OrderService orderServiceBean = applicationContext.getBean("orderServiceBean", OrderService.class);
orderServiceBean.delete();
}
通过构造方法注入的时候:
● 可以通过下标
● 可以通过参数名
● 也可以不指定下标和参数名,可以类型自动推断。