Le framework Spring est créé en raison de la complexité du développement de logiciels. Spring utilise des javabeans de base pour faire des choses qui n'étaient auparavant possibles que par EJB. Cependant, le but de Spring ne se limite pas au développement côté serveur. Du point de vue de la simplicité, de la testabilité et du couplage lâche, la plupart des applications Java peuvent bénéficier du printemps. Le printemps est un cadre de conteneur de contrôle de contrôle léger (CIO) et axé sur la section (AOP).
◆ Objectif: résoudre la complexité du développement d'applications d'entreprise
◆ Fonction: utilisez JavaBean de base au lieu de l'EJB et fournit plus de fonctions d'application d'entreprise
◆ Portée: toute application Java
L'inversion du contrôle (CIO en abréviation anglaise) donne le droit de créer des objets au cadre, qui est une caractéristique importante du cadre et n'est pas un terme spécial pour la programmation orientée objet. Il comprend l'injection de dépendance et la recherche de dépendance. Dans la couche commerciale traditionnelle, lorsque des ressources sont nécessaires, de nouvelles ressources se trouvent dans la couche commerciale, de sorte que le couplage (interdépendance et corrélation entre les programmes) est plus élevé. Maintenant, remettez la nouvelle partie au ressort pour obtenir une cohésion élevée et un couplage faible. En bref: à l'origine, chaque fois que la méthode de couche DAO ou de couche de service était appelée, l'application utiliserait de nouvelles, et maintenant les nouveaux droits ont été remis au printemps, et les ressources nécessaires ont été obtenues à Spring!
1. Téléchargez le package de pot de dépendance requis pour le cadre
Le site officiel du printemps est: http://spring.io/
Téléchargez le package JAR: http://repo.springsource.org/libs-release-local/org/springframework/spring
2. Importez le package JAR de base
En fait, les pots de base de base incluent les grains; contexte; noyau; packages d'expression, et les autres dépendent des journaux log4j. Bien sûr, les pots de printemps sont plus que cela, ils sont ajoutés lentement au stade ultérieur.
3. Configurer le fichier de configuration log4j
Le fichier journal est défini dans le répertoire SRC
### Messages de journal direct vers STDOUT ### log4j.appender.stdout = org.apache.log4j.consoleAppenderLog4j.appendender.stdout.target = System.errlog4j.appender.stdout.layout = org.apache.log4j.patternlayoutlog4j.apprender.stdout.layout.ConversionPattern =% d {Absolute. % c {1}:% l -% m% n ### Messages directs pour déposer mylog.log ### log4j.appender.file = org.apache.log4j.fileAppenderlog4j.appendender.file.file = c /: mylog.loglog4j.appendender.file.layout = org.apache.log4j.patternlayoutlog4j.apprender.file.layout.ConversionPattern =% d {Absolute. % C {1}:% L -% m% n ### Set Log Niveaux - Pour plus de changement de journalisation verbeux 'Info' en 'Debug' ### log4j.rootlogger = info, stdout4. Testez si le fichier journal est déployé avec succès
package com.clj.demo1; import org.apache.log4j.logger; import org.junit.test; / ** * Utilisation du journal de démo * @Author Administrator * * / public class Demo1 {// Create Log Class Logger Logger Log = Logger.getLogger (Demo1.Class); @Test public void run1 () {// Modifiez les informations dans l'attribut log4j.rootlogger à OFF, et log.info ("exécuter"); }}5. Définissez une interface et implémentez la classe
interface:
package com.clj.demo2; Interface publique UserService {public void sayshello ();}Classe d'implémentation
package com.clj.demo2; public class userserviceIMPl implémente userService {nom de chaîne privé; public String getName () {Nom de retour; } public void setName (string name) {this.name = name; } public void init () {System.out.println ("Initialize .."); } public void sayshello () {System.out.println ("Hello Spring" + "/ t" + name); } public void destory () {System.out.println ("Destren .."); }}6. Définir les fichiers de configuration spécifiques au ressort
Définissez le nom d'ApplicationContext.xml, l'emplacement est SRC, le même répertoire que le fichier journal, importez les contraintes correspondantes et injectez la classe d'implémentation dans le fichier de configuration. Commencez simplement par le début, utilisez des contraintes de bean
<? 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: p = "http://www.springframework.org/schema/p" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/Beans/spring-Springsd" BEAN TAGE 1. La valeur de l'ID est unique (doit écrire) 2. Remarque: La classe est la mise en œuvre de classe de classe, pas une interface (doit écrire) 3. Le travail d'initialisation avant l'exécution de la méthode de base (Sélectionner l'écriture) 4. Le travail d'initialisation après l'exécution de la méthode de base (SELECT WRITE) -> <anter id = userService "Init-Method =" Init "Détrave-Method =" Destory "> <Property Name =" nom " </bEAN> </EANS>
7. Test
classe publique Demo1 {/ ** * Original Way * / @Test public void run () {// Créer une classe d'implémentation UserserServiceImpl S = new UserServiceImpl (); S.SetName ("Jaxiansen"); S.Sayhello (); } / ** * Old Factory Version Beanfactory * Old Factory ne créera pas d'objets de fichier de configuration * / @Test public void run2 () {beanfactory factory = new XMLBeAnFactory (new classPathResource ("applicationContext.xml")); UserService us = (userService) factory.getBean ("userService"); us.sayhello (); } / ** * Utilisez la méthode Spring Framework IOC * Créez un serveur de démarrage dans la nouvelle version de l'usine pour créer un objet de fichier de configuration, et il n'est pas nécessaire de charger l'usine lors de l'appel à nouveau * / @Test public void run3 () {// Créer l'usine et le chargement du fichier de configuration principale (news newspathxmlapplicationContex ClassPathxMlApplicationContext ("ApplicationContext.xml"); // obtient l'objet de l'usine (valeur d'ID dans le fichier de configuration, le polymorphisme est utilisé ici) UserService user = (userService) ac.getBean ("userService"); // appelle la méthode de l'objet pour exécuter usi.sayhello (); } / ** * Méthode Demo Destrement-Method * La méthode Bean Detrère ne sera pas exécutée automatiquement * à moins qu'elle ne soit automatiquement appelée dans Scope = Singleton ou dans un conteneur Web, la fonction principale ou le cas de test doit être appelé manuellement (Besoin d'utiliser la méthode close () de classpathxmlapplicationContext) * / @Test Public Void run4 () {// Créer une information et de charger le fichier de configuration central (ClassPathxmlApplicationContext se trouve sous SRC) ClassPathxmlApplicationContext AC = new ClassPathxMlApplicationContext ("ApplicationContext.xml"); // obtient l'objet de l'usine (valeur d'ID dans le fichier de configuration, le polymorphisme est utilisé ici) UserService user = (userService) ac.getBean ("userService"); // appelle la méthode de l'objet pour exécuter usi.sayhello (); // La classe d'implémentation ApplicationContext fournit une méthode étroite, et l'usine peut être fermée et la méthode destory-méthode peut être exécutée. }}La différence entre les anciennes usines et les nouvelles usines
* Différence entre BeanFactory et ApplicationContext
* Beanfactory - Beanfactory prend un chargement paresseux, et le haricot ne sera initialisé que lorsque vous obtenez la première fois
* ApplicationContext - Lors du chargement d'applicationContext.xml, une instance spécifique de l'objet bean sera créée et certaines autres fonctions sont fournies.
* Livraison des événements
* Assemblage automatique Bean
* Implémentations de contexte de diverses couches d'application
Résumé: Il s'agit de la démo la plus fondamentale, qui configure la classe d'implémentation dans le fichier de configuration de ressort. Chaque fois que le serveur est démarré, le fichier de configuration sera chargé, instanciant ainsi la classe d'implémentation.
1. Qu'est-ce que l'injection de dépendance?
Le printemps peut organiser efficacement des objets de niveaux d'application J2EE. Qu'il s'agisse de l'objet d'action de la couche de contrôle, de l'objet de service de la couche commerciale ou de l'objet DAO de la couche de persistance, il peut être coordonné organiquement et exécuter sous la direction du printemps. Le printemps organise des objets de chaque couche ensemble d'une manière lâche. Les objets d'action n'ont pas besoin de se soucier de l'implémentation spécifique d'objets de service, les objets de service n'ont pas besoin de se soucier de l'implémentation spécifique d'objets de couche persistante et les appels vers chaque objet de couche sont complètement orientés vers l'interface. Lorsque le système doit être refactorisé, la quantité de réécriture de code sera considérablement réduite. L'injection de dépendance rend le haricot et le haricot organisés dans des fichiers de configuration, plutôt que d'être codés en dur. Comprendre l'injection de dépendance
L'injection de dépendance et l'inversion du contrôle sont le même concept. La signification spécifique est: lorsqu'un rôle (peut-être une instance Java, appelant) a besoin de l'aide d'un autre rôle (une autre instance Java, appelant), dans le processus de programmation traditionnel, l'appelant est généralement créé par l'appelant. Mais au printemps, le travail de création de la Callee n'est plus effectué par l'appelant, il est donc appelé l'inversion de contrôle; Le travail de création de l'instance Callee est généralement effectué par le conteneur à ressort puis injecté dans l'appelant, il est donc également appelé injection de dépendance.
Qu'il s'agisse d'injection de dépendance ou d'inversion de contrôle, cela signifie que le printemps adopte un moyen dynamique et flexible de gérer divers objets. Les implémentations spécifiques entre les objets sont transparentes les unes aux autres.
2. Le concept de CIO et de DI
* IOC - Inverse du contrôle, inversion de contrôle, inversez la droite de la création de l'objet au printemps! !
* Di - injection de dépendance, injection de dépendance, lorsque le cadre de ressort est responsable de la création d'objets de haricot, injectant dynamiquement des objets de dépendance dans le composant Bean! !
3. Demo
Pour les variables des membres de la classe, il existe deux méthodes d'injection courantes.
Injection de méthode de l'ensemble de propriétés et d'injection de méthode du constructeur
Démontrer d'abord le premier type: l'injection de méthode de jeu de propriétés
1) couche persistante
package com.clj.demo3; classe publique CustomerDaoimpl {public void Save () {System.out.println ("Je suis dao de la couche de persistance"); }}2) Couche commerciale
Remarque: Pour le moment, je souhaite injecter la couche de persistance dans la couche commerciale et remettre le droit de créer l'instance de couche de persistance dans le cadre, la condition est que la couche commerciale doit fournir les attributs des membres et définir des méthodes de la couche de persistance.
Package com.clj.demo3; / ** * La dépendance injecte la couche DAO dans la couche de service * @Author Administrator * * / public class CustomerServiceImpl {// Fournir un zodiac membre, fournir la méthode définie CustomerDaOIMPL CustomerDAO; public void setCustomerDao (CustomerDaoimpl CustomerDAO) {this.CustomerDao = CustomerDAO; } public void Save () {System.out.println ("Je suis le service ..."); // 1. Méthode d'origine // new CustomerDaoimpl (). Save (); //2.spring ioc méthode CustomerDao.Save (); }}3) Configuration du fichier de configuration
<! - Démonstration Dependency Injection -> <bean id = "CustomerDao" /> <bean id = "ClientService"> <! - Injecter Dao in Service Layer -> <propriété name = "CustomerDao" ref = "CustomerDao"> </paremat> </-bean>
4) tester
/ ** * Spring Dependency Injection Method * Inject Dao couche dans le service de service * / @Test public void run2 () {// Créer l'usine, charger le fichier de configuration, et le service client est créé, créant ainsi CustomerDao ApplicationContext context = new ClassPathxMlApplicationContext ("applicationContext.xml"); CustomerServiceImpl CSI = (custiryServiceImpl) context.getBean ("Cust coutiveService"); csi.save (); }Le deuxième type: injection de méthode de construction
1) Classe Pojo et fournir des méthodes de constructeur
package com.clj.demo4; / ** * La méthode d'injection de démonstration * @Author Administrator * * / public class car1 {private String cname; double prix privé; public car1 (String cname, double prix) {super (); this.cname = cname; this.price = prix; } @Override public String toString () {return "car1 [cname =" + cname + ", prix =" + prix + "]"; }}2) Configuration du fichier de configuration
<! - Démontrer la méthode d'injection de la méthode de construction -> <bean id = "car1"> <! - Méthode d'écriture 1 <constructor-arg name = "cname" value = "bmw" /> <constructor-arg name = "price" value = "400000" /> -> <! - Write Method 2 -> <Constructor-arg index = "0" value = "bmw" /> <constructor -ar-index = "1" Value = "400000" /> </EAN>
3) tester
@Test public void run1 () {applicationContext ac = new ClassPathXmlApplicationContext ("ApplicationContext.xml"); Car1 car = (car1) ac.getBean ("car1"); System.out.println (Car); }Extension: la construction de la méthode injecte un objet dans un autre
1) Classe Pojo: But: Injectez la voiture dans la colonne ci-dessus en humains et faites-en l'un des attributs. Dans cette classe, les attributs membres de la voiture doivent être fournis et des méthodes de construction paramétrées doivent être fournies.
package com.clj.demo4; Personne de classe publique {nom de chaîne privée; Car1 Car1; Personne publique (nom de chaîne, car1 car1) {super (); this.name = name; this.car1 = car1; } @Override public String toString () {return "personne [name =" + name + ", car1 =" + car1 + "]"; }}2) Fichier de configuration
<! - Constructor-arg name = "name" value = "jaxiansen" /> <constructor-arg name = "car1" ref = "car1" /> </-bean>
4. Comment injecter un tableau de collection
1) Définissez la classe Pojo
Package com.clj.demo4; import java.util.arrays; import java.util.list; import java.util.map; import java.util.properties; import java.util.set; / ** * démontrer le moyen de définir l'injection * @author administrateur * * / public class utilisateur {private string [] arrrs; Liste privée <string> liste; sets privé <string> sets; Carte privée <String, String> Map; Propriétés privées Pro; public void setPro (Properties pro) {this.pro = pro; } public void setSets (set <string> sets) {this.sets = sets; } public void setMap (map <string, string> map) {this.map = map; } public void setList (list <string> list) {this.list = list; } public void setArrrs (string [] arrrs) {this.arrs = arrrs; } @Override public String toString () {return "utilisateur [arrs =" + arrays.tostring (arrs) + ", list =" + list + ", sets =" + sets + ", map =" + map + ", pro =" + pro + "]"; }}2) Fichier de configuration
<! - Set d'injection -> <bean id = "user"> <! - Array -> <propriété name = "arrs"> <sist> <value> nombre1 </value> <value> nombre2 </ value> <value> nombre3 </value> </sist> </ propriété> <! - list set -> <propriété name = "list"> <s list> <value> jin zazhong </value>> <value> wang jie> </value> jin zazhong </value> <value>> wang jie> </value> jin zaizhong </ propriété> <! - set set -> <propriété name = "sets"> <set> <value> haha </value> <value> haha </value> </ set> </ propriété> <! - Map set -> <propriété name = "map"> <map> <entrée = "aa" value = "rainbow" /> <entry key = "bb" value = "hellowvenus" /> <! <propriété name = "pro"> <props> <prop key = "username"> root </prop> <prop key = "mot de passe"> 123 </prop> </props> </ propriété> </ bean>
3) tester
/ ** * Test Injection Collection * / @Test public void run3 () {applicationContext ac = new ClassPathXmlApplicationContext ("ApplicationContext.xml"); Utilisateur utilisateur = (utilisateur) ac.getBean ("utilisateur"); System.out.println (utilisateur); }5. Comment se développer dans les modules
Ajoutez la balise <import> au fichier de configuration principale (supposons que, un fichier de configuration applicationContex.xml est défini dans le package com.clj.test)
<! - Présentation d'autres fichiers de configuration par développement de modules -> <importation ressource = "com / clj / test / applicationcontext2.xml" />
1. Pour commencer
1).
En plus des 6 packages précédents, vous avez également besoin d'un package Spring-AOP pour jouer l'annotation.
2). Couche de persistance et couche d'implémentation (les interfaces sont ignorées ici)
Couche persistante
Package com.clj.demo1; import org.springframework.context.annotation.scope; import org.springframework.sterreotype.Component; import org.springframework.sterreo-usetory UserDao {@Override public void Save () {System.out.println ("Enregistrer le client .."); }}Couche d'affaires
package com.clj.demo1; import javax.annotation.posstructruct; import org.springframework.beans.factory.annotation.autowired; import org.springframework.beans.factory.annotation.qualifier; import org.springframework.beans.factory.annotation.value; org.springframework.sterreotype.Component; public class userserviceIMPl implémente userService {@Override public void sayshello () {System.out.println ("bonjour printemps"); }}3). Définir le fichier de configuration
Pour le moment, les contraintes doivent ajouter des contraintes de contexte et ajouter une analyse des composants
<? 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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here --> <!-- Open annotation scan: base-package specifies scan face package --> <context:component-scan Base-Package = "com.clj.demo1" /> </ beans>
4) Ajouter des annotations à la classe d'implémentation
/ ** * Annotation des composants, qui peut être utilisée pour marquer la classe actuelle * similaire à <bean id = "userService"> * la valeur signifie donner un alias pour la classe * / @ composante (valeur = "userService") Classe publique UserServiceImpll implémente UserService {// Omis}5) Écrire des tests
/ ** * Méthode d'annotation * / @Test public void run2 () {applicationContext ac = new ClassPathxmlApplicationContext ("ApplicationContext.xml"); UserService US = (UserService) ac.getBean ("UserService"); us.sayhello (); }2. À propos des attributs communs de gestion des haricots
1. @Component: Composant. (a agi sur la classe) L'annotation la plus primitive, il est acceptable d'écrire ceci pour toutes les classes qui ont besoin d'annotation, c'est général
2. Trois annotations dérivées de @Component sont fournies au printemps: (les fonctions sont actuellement cohérentes)
* @Controller - travaille sur la couche Web
* @Service - agit au niveau commercial
* @Repository - Agissant sur la couche de persistance
* Remarque: ces trois annotations sont destinées à rendre le but de la classe d'annotation elle-même, et le ressort l'améliorera dans les versions suivantes.
3. Annotations pour l'injection d'attribut (Remarque: Lorsque vous utilisez l'injection d'annotation, vous ne pouvez pas avoir besoin de fournir une méthode définie)
* S'il s'agit d'un type d'injection normal, vous pouvez utiliser l'annotation de la valeur
* @Value - pour injecter des types normaux
* Si le type d'objet injecté, utilisez l'annotation suivante
* @Autowired - Par défaut, le type est automatiquement assemblé par type, et cela n'a rien à voir avec le nom de classe de la classe injectée.
* Si vous souhaitez injecter par son nom
* @Qualificier - L'utilisation forcée de l'injection de nom doit être utilisée avec Autowired, spécifier le nom de classe et lié au nom de classe injecté
* @Resource - équivalent à @Autowired et @qualifier
* Impliquer: Annotations fournies par Java
* L'attribut utilise l'attribut de nom
4. Annotation de la portée du haricot
* Annoté en tant que @scope (valeur = "prototype"), qui est utilisé sur la classe. Les valeurs sont les suivantes:
* singleton - singleton, valeur par défaut
* Prototype - plusieurs cas
5. Configuration du cycle de vie du haricot (comprendre)
* L'annotation est la suivante:
* @PostConstruct - équivalent à init-méthode
* @Predestroy - équivalent à détruire la méthode
1. Démontrer l'annotation des objets d'attribut
Condition: Injecter les attributs (nom) et objet (userdaoimpl) dans la couche commerciale en numérisant.
1) Ouvrez la couche de persistance pour scanner l'annotation
// @ composant (value = "userdao") Classe universelle annotation @ repository (value = "ud") public class userDaoimpl implémente userdao {@Override public void Save () {System.out.println ("Enregistrer le client .."); }}2) La couche commerciale fournit des annotations pour les attributs et les objets
package com.clj.demo1; import javax.annotation.posstructruct; import org.springframework.beans.factory.annotation.autowired; import org.springframework.beans.factory.annotation.qualifier; import org.springframework.beans.factory.annotation.value; org.springframework.sterreotype.component; / ** * Annotation des composants, peut être utilisé pour marquer la classe actuelle * similaire à <bean id = "userService"> * Value signifie donner un alias à la classe * /// @ scope (valeur = "grototype") plusieurs colonnes (Singletypeypey est une colonne unique) @COMPOINGE (valeur = "uservice"). // Attribut Annotation: il équivaut à injecter la chaîne spécifiée dans l'attribut de nom. La méthode setName peut être omise sans écrire @value (valeur = "jaxiansen") nom de chaîne privée; / ** * Méthode d'injection de référence 1: Autowired () * Méthode d'injection de référence 2: Autowired () + qualificatif * Méthode d'injection de référence 3: @Resource (name = "userdao") Java Méthode, identifier l'injection par nom * / // Autowired () est automatiquement assemblé et injecté par type (désadventages: Parce qu'il correspond par type, alors il n'est pas très précis) @Qualifier (value = "ud") // injection par nom, il doit être utilisé avec Autowired. Les deux peuvent spécifier la classe Private UserDAO UserDAO; // Notez que la valeur de la qualification est le nom d'annotation en haut du nom de classe userdaoimpl, ou vous pouvez spécifier le nom d'ID du bean dans le fichier de configuration / * public void setName (nom de chaîne) {this.name = name; } * / @Override public void sayshello () {System.out.println ("Hello Spring" + name); userDao.save (); } // @postConstruct Tag Annotation for Initialisation in Action Lifecycle @postConstruct public void init () {System.out.println ("Initialize ..."); }}3) Le fichier de configuration doit uniquement être activé pour scanner tous les fichiers de configuration
<? 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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here --> <!-- Open annotation scan: base-package specifies scan face package --> <context:component-scan Base-Package = "com.clj.demo1" /> </ beans>
Remarque: Quant aux collections, il est recommandé d'utiliser des fichiers de configuration
2. Spring Framework intègre les tests unitaires JUnit
1) Ajouter le package de dépendance requis Spring-Test.jar
Remarque: MyEclipes est livré avec son propre environnement Junit, mais parfois en raison de problèmes de version, un nouvel environnement Junit peut être nécessaire. Ici, j'ai téléchargé un nouveau package JAR JUIT-4.9 en ligne. Si MyEclipes est plus récent, vous n'avez pas besoin de le considérer.
2) Écrivez une classe de test et ajoutez des annotations correspondantes
@Runwith et @contextconfiguration (ceci est utilisé pour charger le fichier de configuration, car le chemin par défaut de webroot est un répertoire de premier niveau, plus pour déterminer que SRC est un répertoire de premier niveau)
package com.clj.demo2; import javax.annotation.resource; import org.junit.test; import org.junit.runner.runwith; import org.springframework.test.context.contextConfiguration com.clj.demo1.userservice; @runwith (springjunit4classrunner.class) @ContextConfiguration ("classpath: applicationContext.xml") public class Demo2 {@Resource (name = "userService") Utilisateur privé pour le service utilisateur; @Test public void run1 () {userService.sayHello (); }}6. AOP de Spring Framework
1. Qu'est-ce que AOP
* Dans l'industrie du logiciel, AOP est l'abréviation de la programmation orientée vers l'aspect, signifiant: programmation facette, modularité fonctionnelle
* AOP est un paradigme de programmation, affilié à la catégorie du travail doux, guidant les développeurs comment organiser les structures de programme
* L'AOP a été proposé pour la première fois par l'organisation AOP Alliance et a formulé un ensemble de normes. Spring a introduit des idées AOP dans le cadre et doit respecter les spécifications de l'AOP.
* Une technologie pour réaliser un maintien unifié des fonctions de programme grâce à la précompilation et aux agents dynamiques pendant l'exécution
* AOP est une continuation de la POO, un sujet brûlant dans le développement de logiciels, une partie importante du cadre de printemps et un paradigme dérivé de la programmation fonctionnelle.
* En utilisant AOP, diverses parties de la logique métier peuvent être isolées, réduisant ainsi le couplage entre les parties de la logique métier, améliorant la réutilisabilité du programme et améliorant l'efficacité du développement.
AOP adopte un mécanisme d'extraction horizontal, en remplaçant le code répétitif du système de succession verticale traditionnelle (surveillance des performances, gestion des transactions, inspection de la sécurité, mise en cache)
2. Pourquoi étudier AOP
* Le programme peut être amélioré sans modifier le code source! ! (Créez un proxy pour une méthode fixe. Avant d'accéder à la méthode, entrez d'abord le proxy. Dans le proxy, vous pouvez écrire plus de fonctions pour rendre la méthode plus puissante et améliorer le programme)
AOP: programmation orientée, modulalise tout, chaque module est relativement indépendant, les modules peuvent être partagés (les mêmes) et différents sont particulièrement personnalisés. Utilisez-le au lieu de la programmation verticale traditionnelle pour améliorer la réutilisabilité du programme
3. Implémentation AOP (principe de mise en œuvre)
L'implémentation de AOP comprend deux méthodes proxy <1> pour implémenter les interfaces de classe: utilisez JDK Dynamic Proxy <2> non implémentée Interfaces de classe: Utilisez CGLIB dynamic proxy
1. Implémentez JDK Dynamic Proxy
1) Définir la classe d'implémentation de l'interface de la couche de persistance
package com.clj.demo3; interface publique UserDao {public void Save (); public void update ();} package com.clj.demo3; classe publique UserDaoimpl implémente userdao {@Override public void Save () {System.out.println ("Save User"); } @Override public void Update () {System.out.println ("Modifier l'utilisateur"); }}2) Définir la classe d'outils de proxy dynamique JDK
Cette classe d'outils ajoute certaines fonctions lors de l'exécution de la méthode de sauvegarde de la couche de persistance, et en développement, il est nécessaire d'améliorer une méthode sans modifier le code source.
Package com.clj.demo3; Importer java.lang.reflect.invocationhandler; import java.lang.reflect.method; import java.lang.reflect.proxy; / ** * générer des objets proxy dans jdk (démonstrate aop principes) * @Author Administrator * * / public classe MyproxyUls {public userdao getProxy (final userdao dao) {// Utilisez la classe proxy pour générer des objets proxy userdao proxy = (userdao) proxy.newproxyinstance (dao.getclass (). getClassOader (), dao.getclass (). getInterfaces (), new invocationhandler () {// tôt en tant que proxy objet Executed, the InvocationHeler () {//to dès que le proxy est exigeant, l'exécution Invocation () {// tôt en tant que proxy objet Executed, InvocationHandler () {// tôt en tant que proxy est EXECTINGE La méthode sera exécutée une fois que l'objet public invoque (proxy d'objet, méthode de la méthode, objet [] args) lance Thrownable {// proxy représente la méthode d'objet proxy actuel // méthode exécutée par l'objet actuel // args Paramètres encapsulés // Laisse la classe de classe ou de mise à jour exécutée normalement if (SAVE ".Equals (méthode.getName ()) {System.out.out.PrintLn ("); transaction} return method.invoke (dao, args);}}); retour proxy; }}3) tester
package com.clj.demo3; import org.junit.test; classe publique Demo1 {@Test public void run1 () {// Obtenez l'objet cible userdao dao = new UserDaoimpl (); dao.save (); dao.update (); System.out.println ("=========================================================== =========================================================================================. Utilisez la classe d'outils pour obtenir l'objet proxy userdao proxy = myproxyutils.getproxy (dao);2. Mettre en œuvre la technologie CGLIB
1) Définissez la couche de persistance, il n'y a pas d'interface pour le moment
package com.clj.demo4; classe publique bookdaoimpl {public void Save () {System.out.println ("Save Book"); } public void Update () {System.out.println ("Modifier le livre"); }}2) Écrire des classes d'outils
package com.clj.demo4; import java.lang.reflect.method; import org.springframework.cglib.proxy.enhancer; import org.springframework.cglib.proxy.methodinterceptor; import org.springframework.cglib.proxy.methodproxy; Méthode proxy CGLIB * @Author Administrator * * / public class MyCglitulils {/ ** * générer un objet proxy en utilisant la méthode CGLIB * @return * / public static bookDaoimpl getProxy () {Enhancer Enhancer = new Dehancer (); // Définissez le parent de classe Enhancer.SetSuperclass (bookdaoImpl.class); // Définit la fonction de rappel Enhancer.SetCallback (new MethodInterceptor () {@Override public Object Intercept (objet obj, méthode méthode, objet [] objs, méthodyproxy methetho exécuté ");} return methodproxy.invokesuper (obj, objs); // est la méthode exécutée}}); // Générez l'objet proxy bookdaoimpl proxy = (bookdaoimpl) Enhancer.create (); retour proxy; }}3) Écrire des classes de test
package com.clj.demo4; import org.junit.test; classe publique Demo1 {@Test public void run1 () {// objet cible bookdaoimpl dao = new bookdaoimpl (); dao.save (); dao.update (); System.out.println ("==============================); BookDaoimpl Proxy = MyCglubleS.getProxy (); proxy.save (); proxy.update ();}}}3. Développement AOP de Spring basé sur AspectJ (méthode du fichier de configuration)
1) Déployez l'environnement et importez le package JAR correspondant
2) Créer des fichiers de configuration et introduire des contraintes AOP
<Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: aop = "http://www.springfrrame XSI: ScheMalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd ">
3) Créer des interfaces et implémenter des classes
package com.clj.demo5; interface publique CustomerDao {public void Save (); public void update ();} package com.clj.demo5; / ** * Utilisez le fichier de configuration pour interpréter AOP * @Author Administrator * * / public class CustomerDaOimpl implémente CustomerDAO {@Override public void Save () {// Simuler Exception // int a = 10/0; System.out.println ("Enregistrer le client"); } @Override public void Update () {// TODO Méthode générée automatique Stub System.out.println ("Mise à jour du client"); }}4) Définissez la classe Facet
package com.clj.demo5; import org.aspectj.lang.proceedingjoinpoint; / ** * class de facet: point de saisie + notification * @author administrateur * * / public class myaSpectXml {/ ** * notification (logic spécifique) * / public void Log () {system.out.println ("journal log"); } / ** * La méthode est exécutée avec succès ou les exceptions seront exécutées * / public void après () {System.out.println ("Notification finale"); } / ** * Une fois la méthode exécutée, la notification de publication est exécutée. Si une exception se produit dans le programme, la notification de la publication ne sera pas exécutée * / public void afterreturn () {System.out.println ("Post Notification"); } / ** * Une fois la méthode exécutée, s'il existe une exception, la notification d'exception sera exécutée * / public void after-throwing () {System.out.println ("Exception Notification"); } / ** * Notification surround: la notification est faite avant et après l'exécution de la méthode. * Par défaut, la méthode de l'objet cible ne peut pas être exécutée et l'objet cible doit être exécuté manuellement * / public void autour (ProcedingJoinpoint JOINPPOINT) {System.out.println ("WAVE Notification 1"); // Laissez manuellement la méthode de l'objet cible exécuter Try {joinpoint.proceed (); } Catch (Throwable E) {// TODO Bloc de capture généré automatiquement e.printStackTrace (); } System.out.println ("NOTIFICATION DE RAPPORT 2"); }}5) Injecter des classes d'implémentation et des classes de facettes
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --> <!-- 配置客户的dao --> <bean id="customerDao"/> <!-- 编写切面类配置好--> <bean id="myAspectXml"/> <!-- 配置AOP --> <aop:config> <!-- 配置切面类:切入点+通知(类型)--> <aop:aspect ref="myAspectXml"> <!-- 配置前置通知,save方法执行之前,增强方法会执行--> <!-- 切入点表达式:execution(public void com.clj.demo5.CustomerDaoImpl.save()) --> <!-- 切入点表达式: 1.execution()固定的,必写2.public可以省略不写3.返回值必写,严格根据切入点方法而定,否则增强方法不会执行,可以用*代替,表示任意的返回值4.包名必写,可以用*代替(如:*..*(默认所有包); com.clj.*) 5.类名必写,可以部分用*(如*DaoImpl表示以'DaoImpl'结尾的持久层实现类),但不建议用*代替整个类名6.方法必写,可以部分用*(如save*表示以'save'开头的方法),但不建议用*代替整个类名7.方法参数根据实际方法而定,可以用'..'表示有0或者多个参数--> <!-- <aop:before method="log" pointcut="execution(public void com.clj.*.CustomerDaoImpl.save(..))"/> --> <aop:before method="log" pointcut="execution(* *..*.*DaoImpl.save*(..))"/> </aop:aspect> </aop:config></beans>
6)测试
package com.clj.demo5;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo1 { @Resource(name="customerDao") private CustomerDao customerDao; @Test public void run(){ customerDao.save(); customerDao.update(); }}扩展:切面类升级
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --> <bean id="myAspectXml"/> <aop:config> <aop:aspect ref="myAspectXml"> <!-- 配置最终通知<aop:after method="after" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>--> <!-- 配置后置通知<aop:after-returning method="afterReturn" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>--> <!-- 配置异常通知<aop:after-throwing method="afterThrowing" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>--> <aop:around method="around" pointcut="execution(* *..*.*DaoImpl.update*(..))"/> </aop:aspect> </aop:config></beans>
4、Spring框架AOP之注解方式
1)创建接口和实现类
package com.clj.demo1;public interface CustomerDao { public void save(); public void update();} package com.clj.demo1;public class CustomerDaoImpl implements CustomerDao{ @Override public void save() { // TODO Auto-generated method stub System.out.println("Save customer.."); } @Override public void update() { // TODO Auto-generated method stub System.out.println("Update customer"); }}2)定义切面类
package com.clj.demo1;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;/** * 注解方式的切面类* @Aspect表示定义为切面类*/@Aspectpublic class MyAspectAnno { //通知类型:@Before前置通知(切入点的表达式) @Before(value="execution(public * com.clj.demo1.CustomerDaoImpl.save())") public void log(){ System.out.println("记录日志。。"); } //引入切入点@After(value="MyAspectAnno.fun()") public void after(){ System.out.println("执行之后"); } @Around(value="MyAspectAnno.fun()") public void around(ProceedingJoinPoint joinPoint){ System.out.println("环绕通知1"); try { //让目标对象执行joinPoint.proceed(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("环绕通知2"); } //自定义切入点@Pointcut(value="execution(public * com.clj.demo1.CustomerDaoImpl.save())") public void fun(){ }}3)配置切面类和实现类,并开启自动代理
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 开启自动注解代理--> <aop:aspectj-autoproxy/> <!-- 配置目标对象--> <bean id="customerDao"/> <!-- 配置切面类--> <bean id="myAspectAnno"/></beans>
spring提供了JDBC模板:JdbcTemplate类
1.快速搭建
1)部署环境
这里在原有的jar包基础上,还要添加关乎jdbc的jar包,这里使用的是mysql驱动
2)配置内置连接池,将连接数据库程序交给框架管理,并配置Jdbc模板类
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 先配置连接池(内置) --> <bean id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置JDBC的模板类--> <bean id="jdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean></beans>
3)测试
package com.clj.demo2;import java.sql.ResultSet;import java.sql.SQLException;import java.util.List;import javax.annotation.Resource;import org.apache.commons.dbcp.BasicDataSource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.cglib.beans.BeanMap;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/** * 测试JDBC的模板类,使用IOC的方式* @author Administrator * */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo2 { @Resource(name="jdbcTemplate") private JdbcTemplate jdbcTemplate; /** * 插入*/ @Test public void run1(){ String sql="insert into t_account values(null,?,?)"; jdbcTemplate.update(sql,"李钇林",10000); } /** * 更新*/ @Test public void run2(){ String sql="update t_account set name=? where id=?"; jdbcTemplate.update(sql,"李钇林",1); } /** * 删除*/ @Test public void run3(){ String sql="delete from t_account where id=?"; jdbcTemplate.update(sql,4); } /** * 测试查询,通过主键来查询一条记录*/ @Test public void run4(){ String sql="select * from t_account where id=?"; Account ac=jdbcTemplate.queryForObject(sql, new BeanMapper(),1); System.out.println(ac); } /** * 查询所有*/ @Test public void run5(){ String sql="select * from t_account"; List<Account> ac=jdbcTemplate.query(sql,new BeanMapper()); System.out.println(ac); }}/** * 定义内部类(手动封装数据(一行一行封装数据,用于查询所有) * @author Administrator * */class BeanMapper implements RowMapper<Account>{ @Override public Account mapRow(ResultSet rs, int rowNum) throws SQLException { Account ac=new Account(); ac.setId(rs.getInt("id")); ac.setName(rs.getString("name")); ac.setMoney(rs.getDouble("money")); return ac; } }2、配置开源连接池
一般现在企业都是用一些主流的连接池,如c3p0和dbcp
首先配置dbcp
1)导入dbcp依赖jar包
2)编写配置文件
<!-- 配置DBCP开源连接池--> <bean id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean>
将模板类中引入的内置类datasource改为开源连接池的
3)编写测试类
配置c3p0
1)导入c3p0依赖jar包
2)配置c3p0
<!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean>
将模板类中引入的内置类datasource改为开源连接池的
3)编写测试类
1、什么是事务
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。
2、怎么解决事务安全性问题
读问题解决,设置数据库隔离级别;写问题解决可以使用悲观锁和乐观锁的方式解决
3、快速开发
方式一:调用模板类,将模板注入持久层
1)编写相对应的持久层和也外层,这里省略接口
package com.clj.demo3;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ // Method 1: Inject the jdbc template class into the configuration file and write the template class private in the persistence layer JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public void outMoney(String out, double money) { String sql="update t_account set money=money-? where name=?"; jdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; jdbcTemplate().update(sql,money,in); }} package com.clj.demo4;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //It uses configuration file injection method, and the set method must be provided private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); }}2)配置相对应的配置文件
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean><!-- 配置JDBC的模板类--> <bean id="jdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean><!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean><bean id="accountDao"> <!-- 注入模板类--> <property name="jdbcTemplate" ref="jdbcTemplate"/> <property name="dataSource" ref="dataSource"/> </bean></beans>
3)测试类
package com.clj.demo3;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo1 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //Call the payment method accountService.pay("Jia Xiansen","Li Yilin",100); }}方式二:持久层继承JdbcDaoSupport接口,此接口封装了模板类jdbcTemplate
1)编写配置文件
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean></beans>
2)更改持久层
package com.clj.demo3;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ //Method 1: Inject the jdbc template class into the configuration file and write the template class directly in the persistence layer// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } // Method 2: The persistence layer inherits JdbcDaoSupport, which encloses the template class. The persistence layer of the configuration file does not need to inject the template class, nor does it need to configure the template class public void outMoney(String out, double money) { //jdbcTemplate.update(psc); String sql="update t_account set money=money-? where name=?"; this.getJdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; this.getJdbcTemplate().update(sql,money,in); }}3)更改业务层
package com.clj.demo4;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //It uses configuration file injection method, and the set method must be provided private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); }}4)测试类和上述一样
4、spring事务管理
In order to simplify transaction management code, Spring provides a template class TransactionTemplate, which can be manually programmed to manage transactions. You only need to use this template class! !
1、手动编程方式事务(了解原理)
1)快速部署,搭建配置文件,配置事务管理和事务管理模板,并在持久层注入事务管理模板
配置事务管理器
<!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
配置事务管理模板
<bean id="transactionTemplate"> <property name="transactionManager" ref="transactionManager"/></bean>
将管理模板注入业务层
<bean id="accountService"> <property name="accountDao" ref="accountDao"/> <property name="transactionTemplate" ref="transactionTemplate"/></bean>
全部代码:
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> <property name="transactionTemplate" ref="transactionTemplate"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 手动编码方式,提供了模板类,使用该类管理事务比较简单--> <bean id="transactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean></beans>
2)在业务层使用模板事务管理
package com.clj.demo3;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //Usage configuration file injection method, set method must be provided private AccountDao accountDao; //Inject transaction template class private TransactionTemplate transactionTemplate; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } /** * Method of transfer*/ public void pay(final String out,final String in, final double money) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { //The execution of the transaction, if there is no problem, submit, if Chu Xiang is exception, roll back protected void doInTransactionWithoutResult(TransactionStatus arg0) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); } }); }}3)测试类和上一致
package com.clj.demo4;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext2.xml")public class Demo2 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //Call the payment method accountService.pay("Jia Xiansen","Li Yilin",100); }}申明式事务有两种方式:基于AspectJ的XML方式;基于AspectJ的注解方式
1、XML方式
1)配置配置文件
需要配置平台事务管理
<!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
配置事务增强
<tx:advice id="myAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 给方法设置数据库属性(隔离级别,传播行为) --> <!--propagation事务隔离级别:一般采用默认形式:tx:method可以设置多个--> <tx:method name="pay" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
aop切面类
<aop:config> <!-- aop:advisor,是spring框架提供的通知--> <aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.clj.demo4.AccountServiceImpl.pay(..))"/> </aop:config>
全部代码
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 申明式事务(采用XML文件的方式) --> <!-- 先配置通知--> <tx:advice id="myAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 给方法设置数据库属性(隔离级别,传播行为) --> <!--propagation事务隔离级别:一般采用默认形式:tx:method可以设置多个--> <tx:method name="pay" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 配置AOP:如果是自己编写的AOP,使用aop:aspect配置,使用的是Spring框架提供的通知--> <aop:config> <!-- aop:advisor,是spring框架提供的通知--> <aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.clj.demo4.AccountServiceImpl.pay(..))"/> </aop:config> <!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean></beans>
2)编写持久层和业务层(省略接口)
package com.clj.demo5;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ //Method 1: Inject the jdbc template class into the configuration file and write the template class directly in the persistence layer// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } // Method 2: The persistence layer inherits JdbcDaoSupport, which encloses the template class. The persistence layer of the configuration file does not need to inject the template class, nor does it need to configure the template class public void outMoney(String out, double money) { //jdbcTemplate.update(psc); String sql="update t_account set money=money-? where name=?"; this.getJdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; this.getJdbcTemplate().update(sql,money,in); }} package com.clj.demo5;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.annotation.Transactional;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //It uses configuration file injection method, and the set method must be provided private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); }}3)测试类
package com.clj.demo4;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext2.xml")public class Demo2 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //Call the payment method accountService.pay("Jia Xiansen","Li Yilin",100); }}2、注解方式
1)配置配置文件
配置事务管理
<bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
开启注释事务
<!-- 开启事务的注解--> <tx:annotation-driven transaction-manager="transactionManager"/>
全部代码
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 开启事务的注解--> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean></beans>
2)业务层增加@Transactional
package com.clj.demo5;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.annotation.Transactional;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;//Add this annotation in the current class means that all the current class has transactions @Transactionalpublic class AccountServiceImpl implements AccountService{ //Using configuration file injection method, the set method must be provided private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); }}3)持久层不变
package com.clj.demo5;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ //Method 1: Inject the jdbc template class into the configuration file and write the template class directly in the persistence layer// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } // Method 2: The persistence layer inherits JdbcDaoSupport, which encloses the template class. The persistence layer of the configuration file does not need to inject the template class, nor does it need to configure the template class public void outMoney(String out, double money) { //jdbcTemplate.update(psc); String sql="update t_account set money=money-? where name=?"; this.getJdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; this.getJdbcTemplate().update(sql,money,in); }}4)测试类
package com.clj.demo5;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext3.xml")public class Demo3 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //Call the payment method accountService.pay("Jia Xiansen","Li Yilin",100); }}Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.