prefacio
Los últimos dos años, la red está llena de lecciones "Un día springboot competente" "2 Xiaoshi springboot competente" y otros cursos, creo que muchos principiantes son también de Java springboot back-end comenzó. 2 horas para construir el muelle de fondo arquitecto + MVC + mybatis menudo la gente tiene un sentido de finalización springboot así que al final hay una necesidad de aprender primavera? La respuesta debe ser muy responsable para decirle: es necesario! Simple, fuera de la caja y otras características hacen springboot popular, pero asegúrese de recordar: cuanto más un marco sencillo de usar, la explicación de la trama detrás para hacer el trabajo más complejo para los desarrolladores. En mis ojos springboot sólo un resorte integrado, la integración del Tomcat, Spring MVC algunos componentes comunes, y sigue siendo la esencia de la primavera
Si también la conciencia de la importancia de no primavera, aquí hay algunos caso muy real, si el caso no puede encontrar el problema, competentes primavera favor discreción si o no a escribir su hoja de vida
caso
Dificultad ★: Singleton (por ejemplo: servicio, DAO capa) prohibir el uso de variables miembro no estáticos
Use errores
Los requisitos de negocio es la necesidad de importar sobre 10w billetes de Excel, PagService (Singleton) ImportExcelListener dependiente (Singleton) para la importación de Excel. El uso de Ali EasyExcel, aquí no para discutir el marco, sólo se necesita saber leer cada línea de datos ImportExcelListener llama a la invocación vuelve una fila de datos, leer el final de la línea dará lugar a doAfterAllAnalysed. Teniendo en cuenta la gran cantidad de datos, que cada uno lea una línea inserta una vez al parecer, no es factible, 10w insertar una fila es demasiado grande, los estudiantes poco a Después de la decisión de 1000 para evaluar una fila se inserta
@Service
public class PagService extends BaseService<Pag> {
@Autowired
private ImportExcelListener importExcelListener;
public void improt(File file) {
// 调用importExcelListener实现excel导入
importExcelListener.read(file);
}
}
@Component
public class ImportExcelListener extends AnalysisEventListener<Pag> {
@Autowired
private PagService pagService;
// 用于保存1000张票
List<Pag> list = new ArrayList<Pag>();
@Override
public void invoke(DemoData data, AnalysisContext context) {
// 每获取一张票将票加入list
list.add(data);
// 票数到达1000则批量保存
if (list.size() >= 1000) {
pagService.save(list);
list.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 读到最后一行则批量保存
pagService.save(list);
list.clear();
}
}
causa ERROR
En este proyecto Web se utiliza normalmente, pero dará lugar a un error grave, no seguro para subprocesos! 1. Un punto de negocio de los negocios de importación al mismo tiempo y los datos del punto B, A y B será completamente mezclado 2. Una vez que el programa es anormal, después de la presentación de Excel nunca va a lanzar una excepción índice de violación único
causa
ImportExcelListener
Es @Component
conjunto se convirtió en un solo ejemplo, para utilizar una variables de miembros no estáticos List<Pag> list = new ArrayList<Pag>();
en violación del principio de la utilización de un solo caso, causa problemas hilo inseguro. ImportExcelListener
Como una sola realización, es decir, en el proyecto Web, y habrá un solo caso.
- Cuando A, B, al mismo tiempo se introduce en el negocio de la compra de entradas, utilizando el mismo
ImportExcelListener
el mismolist
, cuando se introduce en unalist
también en el mismo momento de la escritura de datos Blist
está escrito, lo que resulta en el descubrimiento de datos de importación una mezcla de los datos B . - E importación de datos se produce cuando se produce una excepción, por ejemplo, para leer los datos de la línea 501 es anormal, pero la lista contendrá las primeras 500 filas de datos, y no se borra. Mientras que el segundo importado porque
ImportExcelListener
un solo ejemplo, la caché de contenedores COI, por lo tanto,ImportExcelListener
o el originalImportExcelListener
,list
es aún antes de esolist
, los datos posteriores a su vez se unen a la importación 1-500 línealist
, lo que resulta en un único índice de conflictos son siempre de importación
Nivel: ★★: plus @Scope ( "Prototipo") es más casos (modelo prototipo) todavía?
Use errores
Un poco después del descubrimiento del problema, sino también conocer la causa del problema radica en el singleton, por lo que se da por supuesto estarán presentes @Scope("Prototype")
, a ImportExcelListener
convertirse en más casos (es decir, el modelo de prototipo), no es resolver el problema? Un enfoque tal puede realmente resolver el problema?
@Component
@Scope("Prototype")
public class ImportExcelListener extends AnalysisEventListener<Pag> {
...
}
causa ERROR
Un pequeño cambio después de la finalización del código presentado, todavía existe reacción empresarios ERROR, no resuelve
causa
ERROR persiste, entonces ese hilo del problema de la inseguridad sigue existiendo, lo que indica que más casos también se hilo de seguridad? Obviamente no, escenario de múltiples casos utilizado para cada solicitud ImportExcelListener
es un nuevo ejemplo, el caso de interferencia mutua no existe, no hay llamadas cuestiones de hilos de seguridad en absoluto. Entonces, ¿dónde está el problema? Los principales problemas radica en que incluso una pequeña adición de A @Scope("Prototype")
, pero este proyecto ImportExcelListener
sigue siendo un producto único.
La razón es PagService
dependiente ImportExcelListener
, PagService
es una única forma de realización ImportExcelListener
es más casos. Al crear la primavera PagService
, el conocer la dependencia ImportExcelListener
, y ImportExcelListener
es una forma de realización de múltiples, y por lo tanto las de nueva creación importExcelListener@001
de objetos y en la dirección PagService
, creado después de la finalización, PagService
la primavera que se almacenan en caché COI, el contenedor, junto necesaria PagService
cuando se toma directamente de la memoria caché. Por lo tanto, después de la creación, A y taquilla taquilla B llama en realidad PagService
es la misma instancia, lo que llevó a su referencia importExcelListener@001
es el mismo, también dio lugar incluso con @Scope("Prototype")
pero aún así la misma instancia, y por lo tanto seguro para subprocesos ERROR sigue ahí.
Se adjunta a un único ciclo en el presente documento setter diagrama de flujo dependiente de realización, A es PagService
, b es ImportExcelListener
. Cuando PagService
creó por primera vez, se terminará la 1-17步骤
completa PagService
creada. Pero el segundo tiempo necesario ImportExcelListener
cuando, en el paso 1. 尝试从各级缓存中获取bean
devolverá directamente a la caché PagService
, en lugar de ir al tubo ImportExcelListener
no es mucho caso no es necesario volver a crear. Por favor, consulte el ciclo de primavera de la dependencia
★★★ dificultad: Let PagService también se convirtió en más casos!
Use errores
A los compañeros de clase después de que se encontró un pequeño error, el último enojado, luego les permiten todos los casos llegar a ser más! Esto puede tener siempre la razón y en primer lugar, ya sea pequeña Un estudiante no sabe todo el controlador MVC primavera es un caso único? (Nota: marco de trabajo Struts de acción es múltiple de los casos, esta es la principal diferencia con el MVC primavera), y no puede resolver problema. Pero el punto de partida es bueno, por lo que son más casos, lo que parece resolver el problema. Código es el siguiente
@Component
@Scope("Prototype")
public class PagService extends BaseService<Pag> {
@Autowired
private ImportExcelListener importExcelListener;
...
}
@Component
@Scope("Prototype")
public class ImportExcelListener extends AnalysisEventListener<Pag> {
@Autowired
private PagService pagService;
...
}
causa ERROR
Si cree que el código anterior no es ningún problema, a continuación, nos fijamos en los resultados, el proyecto directamente Lianpao se ejecuta hasta
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'pagService': Unsatisfied dependency expressed through field 'importExcelListener'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'importExcelListener': Unsatisfied dependency expressed through field 'pagService'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'pagService': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:667)
...
causa
De hecho, desde la anomalía anterior no podía ver hacia fuera, PagService
y ImportExcelListener
el ciclo de dependencia. A Small dijo que estaba desconcertado, primero secuencia de código secundario es una dependencia circular ah, ¿por qué el primer cuadrática secuencial ningún problema? Esta vez no habrá problemas? Aquí sacar conclusiones, la primavera puede resolver sólo el único dependencias circulares modo de realización, la inyección de setter y un prototipo único patrón para el modo de inyección se construyen resuelto.
punto popular, PagService
a medida que más casos, lo que significa que se requiere cada adquisición es una nueva instancia. Y cuando PagService
el tiempo para crear, resulta necesario recurrir ImportExcelListener
también más casos, también es una nueva producción ImportExcelListener
ejemplo, cuando ImportExcelListener
les resulta necesario recurrir a PagService
, y PagService
sea más casos, no se llevará a la caché, pero crear una nueva y más casos. El resultado es un ciclo de dependencia circular de la muerte, la primavera puede hacer es ayudar usted lanza una excepción ...
primavera dependencia circular es una entrevista favorito para hacer preguntas, cómo detectar dependencias circulares? resorte que puede resolver dependencias circulares? El total se puede atribuir a dos puntos
- Usted debe estar sujeta a la exposición de antemano
- Después del tiempo de exposición a una instancia
Indispensables, dependencias sobre circulares se refieren al ciclo de primavera de la dependencia
soluciones
En estos temas, que se resumen en un único caso citado muchos casos de cómo hacer cada llamada puede asegurar que más casos de este problema. Como veterano extremo posterior de Java de la primavera, ya ofrece soluciones que proporcionan las tres soluciones es aquí por referencia:
- uso oficial o primavera @Lookup <> de búsqueda de métodos de etiquetas, cajas de resolución de problemas simples referencias
- Ali recomendación oficial, este método es el más violento,
ImportExcelListener
la gestión directa sin el uso de la primavera, es decir, sin@Component
etiquetas, lo que permite a los usuarios llamar al método, un nuevo usted mismo. Que está completamente fuera de la gestión de las prácticas de primavera, el cliente responsable de sus propios ejemplos del ciclo de vida
@Service
public class PagService extends BaseService<Pag> {
public void improt(File file) {
ImportExcelListener importExcelListener = new ImportExcelListener(this);
// 调用importExcelListener实现excel导入
importExcelListener.read(file);
}
}
- Lograr BeanFactoryAware, obtenido de la BeanFactory en
ImportExcelListener
más casos, para asegurar que cada llamada por una nueva. Este enfoque no es deseable, ha aumentado el grado de acoplamiento de código, pero nos proporciona otra idea. Percepción de la primavera familiarizados Aware se refiere ciclo de vida de la primavera
@Service
public class PagService extends BaseService<Pag> implements BeanFactoryAware{
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public void improt(File file) {
ImportExcelServic importExcelServic = (ImportExcelServic)beanFactory.getBean("importExcelServic", this);
// 调用importExcelServic实现excel导入
importExcelServic.read(file);
}
}
resumen
- singleton resorte nunca use variables miembro no estáticos (variables miembro estático de una clase sólo uno, no habría ningún hilo de seguridad)
- Singleton se basan más casos, querrá asegurarse de que cada llamada a un nuevo casos de usos múltiples, es necesario utilizar @Lookup o de búsqueda método de la etiqueta
- Sólo un único resorte realización, la solución de inyección conjunto, pero el problema de dependencias cíclicas
También utilice springboot, pero lo hace springboot competentes no significa dos horas para aprender algunas similares @Cacheable tales etiquetas, incluso competentes, y si es así creo que la entrevista va a ser miserable martillo. Mi consejo es aprender primavera, si los estudiantes quieren ir a los mejores fabricantes del sistema puede aprender sobre la fuente de la primavera , estilo de código, ideas de diseño es muy útil. Después de todo, los fabricantes no es probable que pedir al entrevistador que no usará @ cacheable, @ Tranactional otras etiquetas, pero quieren que le diga cómo @Cacheable AOP aspectos de la programación por, aún más es cómo utilizar Jdk dinámico agente o agentes para lograr @Cacheable cglib