1. Tipo de datos de inyección de dependencia de beans
(1) Inyección de tipos de datos comunes
package com.iflytek.dao;
public class UserDaoImpl implements UserDao {
private String company;
private int age;
public void setCompany(String company) {
this.company = company;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void save() {
System.out.println(company + "===" + age);
System.out.println("UserDao save method running....");
}
}
<bean id="userDao" class="com.iflytek.dao.UserDaoImpl">
<property name="company" value="科大讯飞"/>
<property name="age" value="22"/>
</bean>
(2) Inyección del tipo de datos de colección (List<String>)
package com.iflytek.dao;
import java.util.List;
public class UserDaoImpl implements UserDao {
private List<String> strList;
public void setStrList(List<String> strList) {
this.strList = strList;
}
public void save() {
System.out.println(strList);
System.out.println("UserDao save method running....");
}
}
<bean id="userDao" class="com.iflytek.dao.UserDaoImpl">
<property name="strList">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
</bean>
(3) Inyección del tipo de datos de colección (Lista<Usuario>)
package com.iflytek.domain;
public class User {
private int id;
private String name;
private int age;
}
public class UserDaoImpl implements UserDao {
private List<User> userList;
public void setUserList(List<User> userList) {
this.userList = userList;
}
public void save() {
System.out.println(userList);
System.out.println("UserDao save method running....");
}
}
<bean id="u1" class="com.iflytek.domain.User"/>
<bean id="u2" class="com.iflytek.domain.User"/>
<bean id="userDao" class="com.iflytek.dao.impl.UserDaoImpl">
<property name="userList">
<list>
<bean class="com.iflytek.domain.User"/>
<bean class="com.iflytek.domain.User"/>
<ref bean="u1"/>
<ref bean="u2"/>
</list>
</property>
</bean>
(4) Inyección del tipo de datos de recopilación (Map<String,User>)
package com.iflytek.dao;
import com.iflytek.domain.User;
import java.util.Map;
public class UserDaoImpl implements UserDao {
private Map<String, User> userMap;
public void setUserMap(Map<String, User> userMap) {
this.userMap = userMap;
}
public void save() {
System.out.println(userMap);
System.out.println("UserDao save method running....");
}
}
<bean id="u1" class="com.iflytek.domain.User"/>
<bean id="u2" class="com.iflytek.domain.User"/>
<bean id="userDao" class="com.iflytek.dao.UserDaoImpl">
<property name="userMap">
<map>
<entry key="user1" value-ref="u1"/>
<entry key="user2" value-ref="u2"/>
</map>
</property>
</bean>
(5) Inyección de tipo de datos de colección (Propiedades)
package com.iflytek.dao;
import java.util.Properties;
public class UserDaoImpl implements UserDao {
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
public void save() {
System.out.println(properties);
System.out.println("UserDao save method running....");
}
}
<?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="u1" class="com.iflytek.domain.User"/>
<bean id="u2" class="com.iflytek.domain.User"/>
<bean id="userDao" class="com.iflytek.dao.UserDaoImpl">
<property name="properties">
<props>
<prop key="p1">aaa</prop>
<prop key="p2">bbb</prop>
<prop key="p3">ccc</prop>
</props>
</property>
</bean>
<bean id="userService" class="com.iflytek.service.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"/>
</bean>
<bean id="userService2" class="com.iflytek.service.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
</beans>
1.2 Introducir otros archivos de configuración (desarrollo de módulo dividido)
En el desarrollo real, Spring tiene mucho contenido de configuración, lo que hace que la configuración de Spring sea muy complicada y grande, por lo que algunas configuraciones se pueden descomponer en otros archivos de configuración y el archivo de configuración principal de Spring se carga a través de la etiqueta de importación.
<import resource="applicationContext-xxx.xml"/>
2.Vista de alto nivel del contenedor Spring
Cuando se inicia Spring, lee la información de configuración del Bean proporcionada por la aplicación y genera un registro de configuración del Bean correspondiente en el contenedor Spring. Luego crea una instancia del Bean basándose en este registro, ensambla las dependencias entre los Beans y proporciona soporte para la parte superior. aplicación de capa Proporcionar un entorno listo para ejecutar.
3. ¿Qué son IoC y DI?
Ioc- Inversion of Control
, es decir, " 控制反转
", no es una tecnología, sino una idea de diseño.
En el desarrollo de Java, Ioc significa entregar el objeto que diseñó al contenedor para su control, en lugar del control directo tradicional dentro de su objeto.
DI: inyección de dependencia, es decir, "inyección de dependencia": la relación de dependencia entre componentes la determina el contenedor durante el tiempo de ejecución. En sentido figurado, el contenedor inyecta dinámicamente una determinada relación de dependencia en el componente. El propósito de la inyección de dependencia no es aportar más funciones al sistema de software, sino aumentar la frecuencia de reutilización de componentes y construir una plataforma flexible y escalable para el sistema. A través del mecanismo de inyección de dependencia, podemos especificar los recursos requeridos por el objetivo y completar nuestra propia lógica de negocio mediante una configuración simple sin ningún código, sin importar de dónde provienen los recursos específicos o quién los implementa.
3.1 ¿Cuál es la diferencia entre IoC y DI?
La inyección de dependencia DI no es completamente equivalente a IoC. Cabe decir que la inyección de dependencia DI es un método o estrategia de implementación de IoC.
La búsqueda de dependencias y la inyección de dependencias son estrategias de implementación de IoC.
La búsqueda de dependencias consiste en llamar activamente a la interfaz proporcionada por el contenedor IoC en la aplicación para obtener el objeto Bean correspondiente, mientras que la inyección de dependencia consiste en inyectar dependencias a través de constructores, campos, métodos de establecimiento o interfaces cuando se inicia o inicializa el contenedor IoC.
La búsqueda de dependencias es más engorrosa para los desarrolladores que la inyección de dependencias , tiene un cierto grado de intrusión de código y requiere el uso de la interfaz proporcionada por el contenedor IoC, por lo que siempre enfatizamos esto último.
La implementación de la inyección de dependencia en el contenedor IoC también consiste en llamar a la interfaz relevante para obtener el objeto Bean, pero todas estas tareas las implementa el contenedor cuando se inicia el contenedor IoC. En las aplicaciones, generalmente rara vez tomamos la iniciativa de Llame a la interfaz para obtener el objeto Bean.
4.Fuente de datos de configuración de Spring
El papel de la fuente de datos (grupo de conexiones)
- Las fuentes de datos (grupos de conexiones) se utilizan para mejorar el rendimiento del programa, como
- Cree una instancia de la fuente de datos por adelantado e inicialice algunos recursos de conexión
- Obtener de la fuente de datos cuando se utiliza el recurso de conexión
- Devuelva los recursos de conexión a la fuente de datos después de su uso.
- Fuentes de datos comunes (grupos de conexiones): DBCP, C3P0, Druid, etc.
Pasos de desarrollo
-
Importar coordenadas de fuentes de datos y coordenadas basadas en bases de datos
-
Crear objeto de fuente de datos
-
Establecer los datos de conexión básicos de la fuente de datos.
-
Usar fuentes de datos para obtener y devolver recursos de conexión
1.grupo de conexiones druidas
Importar coordenadas de druida
<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
Configurar el archivo applicationContext.xml
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="Url" value="jdbc:mysql://localhost:3306/db1"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
prueba
public class App {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource=(DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
}
}
2.grupo de conexiones c3p0
Importe las coordenadas de c3p0 y druid e importe las coordenadas del controlador de la base de datos mysql
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<!-- C3P0连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
Configurar el archivo applicationContext.xml
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db1"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
prueba
public class App {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource=(DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
}
}
3. Utilice el archivo de configuración para crear un grupo de conexiones Druida.
paso:
1. Abra el espacio de nombres de contexto.
2. Utilice el espacio de contexto para agregar un archivo de propiedades.
3. Utilice el marcador de posición de propiedad ${} para leer las propiedades en el archivo de propiedades.
Configurar el archivo 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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="jdbc.properties"/>
<bean class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="Url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
Nota:
archivo de configuración jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db1
jdbc.username=root
jdbc.password=root
Cargar archivo de propiedades:
5.Desarrollo de anotaciones de primavera
Anotaciones originales de primavera.
Spring es un marco que tiene poco código pero mucha configuración. La configuración es relativamente pesada y afecta la eficiencia del desarrollo. Por lo tanto, el desarrollo de anotaciones es una tendencia. Las anotaciones en lugar de archivos de configuración xml pueden simplificar la configuración y mejorar la eficiencia del desarrollo.
Las anotaciones originales de Spring son principalmente configuraciones alternativas.
El contenido en () no es único.
anotación | ilustrar |
---|---|
@Component(“userDao”) | Usado en clases para crear instancias de beans. |
@Controlador | Se utiliza en clases de capa web para crear instancias de beans. |
@Servicio(“serviciodeusuario”) | Se utiliza en clases de capa de servicio para crear instancias de beans. |
@Repositorio(“usuarioDao”) | Utilizado en clases de capa dao para crear instancias de beans |
@autocableado | Se utiliza en campos para inyección de dependencia según el tipo. |
@Calificatorio | Usado con @Autowired para inyección de dependencia por nombre |
@Recurso | Equivalente a @Autowired+@Qualifier, inyectado según el nombre |
@Valor(" ") | Inyectar propiedades comunes |
@Scope(“singleton”) | Marque el alcance del prototipo de Bean/singleton |
@PostConstruct | Utilice el método para marcar el método como método de inicialización del Bean. |
@PreDestroy | Utilice el método para marcar el método como método de destrucción del frijol. |
Aviso:
Al desarrollar usando anotaciones, debe configurar el escaneo de componentes en applicationContext.xml. La función es especificar qué paquete y los beans bajo sus subpaquetes deben escanearse para identificar las clases, campos y métodos configurados usando anotaciones.
<!--注解的组件扫描(包名)-->
<context:component-scan base-package="com.gz"/>
Nuevas anotaciones de primavera.
Las anotaciones anteriores no pueden reemplazar completamente el archivo de configuración xml. Las configuraciones que deben reemplazarse con anotaciones son las siguientes:
Configuración de beans no personalizados:
Cargue la configuración del archivo de propiedades: contexto:property-placeholder
Configuración del escaneo de componentes: contexto: escaneo de componentes
Importar otros archivos:
anotación | ilustrar |
---|---|
@Configuración | Se utiliza para especificar que la clase actual es una clase de configuración de Spring y las anotaciones se cargarán desde esta clase cuando se cree el contenedor. |
@ComponentScan(“com.gz”) | Se utiliza para especificar los paquetes que Spring escaneará al inicializar el contenedor. La función es la misma que <context:component-scan base-package="com.iflytek"/> en el archivo de configuración xml de Spring. |
@Bean(nombre=“fuente de datos”) | Utilizada en un método, la anotación almacena el valor de retorno del método en el contenedor Spring. |
@PropertySource(“”) | Se utiliza para cargar configuraciones en archivos .properties |
@Importar | Se utiliza para importar otras clases de configuración. |
6.Spring integra Junit
Problemas con las pruebas originales de Junit Spring
En la clase de prueba, cada método de prueba tiene las dos líneas de código siguientes:
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountService as = ac.getBean("accountService",IAccountService.class);
La función de estas dos líneas de código es obtener el contenedor, si no se escribe, se generará directamente una excepción de puntero nulo. Por lo que no se puede eliminar fácilmente.
Ideas para resolver los problemas anteriores.
Deje que SpringJunit sea responsable de crear el contenedor Spring, pero debe decirle el nombre del archivo de configuración.
Inyecte los beans de prueba necesarios directamente en la clase de prueba
Pasos de Junit para la integración de primavera
-
Importar las coordenadas de Spring Integrated Junit.
-
Utilice @Run con anotación para reemplazar el tiempo de ejecución original
-
Utilice @ContextConfiguration para especificar un archivo de configuración o una clase de configuración
-
Utilice @Autowired para inyectar objetos que deben probarse
-
Crear métodos de prueba para realizar pruebas.
⑤Esta es la versión definitiva
Implementación de código Junit integrada en Spring
Importar las coordenadas de Spring Integrated Junit.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
② Utilice la anotación @Run para reemplazar el tiempo de ejecución original
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringJunitTest {
}
③Utilice @ContextConfiguration para especificar el archivo de configuración o la clase de configuración
@RunWith(SpringJUnit4ClassRunner.class)
//加载spring核心配置文件
@ContextConfiguration(value = {
"classpath:applicationContext.xml"})
public class SpringJunitTest {
}
④Utilice @Autowired para inyectar los objetos que deben probarse
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {
SpringConfiguration.class})
public class SpringJunitTest {
@Autowired
private UserService userService;
}
⑤Crear métodos de prueba para realizar pruebas.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = {
"classpath:applicationContext.xml"})
public class SpringJunitTest {
@Autowired
private UserService userService;
@Test
public void testUserService(){
userService.save();
}
}
Las anotaciones introducidas por Junit5 y Junit4 son diferentes.
// Junit4 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(value = { "classpath:applicationContext.xml"}) public class SpringJunitTest { }
// Junit5 @ExtendWith(SpringExtension.class) @ContextConfiguration(value = { "classpath:applicationContext.xml"}) public class SpringJunitTest { }