A estrutura da primavera é criada devido à complexidade do desenvolvimento de software. A primavera usa javabeus básicos para fazer coisas que antes eram possíveis apenas pelo EJB. No entanto, o objetivo da Spring não se limita ao desenvolvimento do lado do servidor. Do ponto de vista da simplicidade, testabilidade e acoplamento frouxo, a maioria dos aplicativos Java pode se beneficiar da primavera. A mola é uma inversão de controle leve (IOC) e estrutura de contêiner orientada para a seção (AOP).
◆ Objetivo: resolver a complexidade do desenvolvimento de aplicativos corporativos
◆ Função: Use Javabean básico em vez de EJB, e fornece mais funções de aplicativos corporativos
◆ Escopo: qualquer aplicativo Java
A inversão do controle (COI em abreviação inglesa) fornece o direito de criar objetos para a estrutura, que é uma característica importante da estrutura e não é um termo especial para programação orientada a objetos. Inclui injeção de dependência e pesquisa de dependência. Na camada de negócios tradicional, quando são necessários recursos, novos recursos são encontrados na camada de negócios, para que o acoplamento (interdependência e correlação entre programas) seja maior. Agora entregue a nova parte à primavera para obter alta coesão e baixo acoplamento. Em resumo: Originalmente, sempre que o método da camada DAO ou camada de serviço era chamado, o aplicativo usava novo e agora os novos direitos eram entregues à primavera, e quais recursos eram necessários foram obtidos na primavera!
1. Faça o download do pacote de jar de dependência necessário para a estrutura
O site oficial da primavera é: http://spring.io/
Baixe o pacote JAR: http://repo.springsource.org/libs-release-local/org/springframework/spring
2. Importe o pacote básico do jar
De fato, os frascos básicos do núcleo incluem feijões; contexto; núcleo; pacotes de expressão e os outros dependem dos logs log4j. Obviamente, os frascos de primavera são mais do que isso, eles são adicionados lentamente no estágio posterior.
3. Configurar arquivo de configuração log4j
O arquivo de log é definido no diretório SRC
### Mensagens de log direto para stdout ###log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.errlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %C {1}: %L - %M %N ### Mensagens diretas para arquivar MyLog.log ### log4j.appender.file = org.apache.log4j.FileAppenderLog4j.appender.file.file = c/: mylog.loglog4j.appender.file.pender.file = org.apache.log4j.patternLayoutLog4j.pender.files %C {1}: %L - %M %N ### Defina os níveis de log - para mais alterações detalhadas do log 'info' para 'Debug' ### log4j.rootlogger = info, stdout4. Teste se o arquivo de log é implantado com sucesso
pacote com.clj.demo1; importar org.apache.log4j.logger; importar org.junit.test;/** * Uso do log de demonstração * @author administrador * */public class Demo1 {// Criar classe de log Logger private Log = Logger.getLogger (Demo1.class); @Test public void run1 () {// altere as informações no atributo log4j.rootlogger para desligar e log.info ("execute"); }}5. Defina uma interface e a classe de implementação
interface:
pacote com.clj.demo2; interface pública UserService {public void dizhello ();}Classe de implementação
pacote com.clj.demo2; classe pública UserServiceImpl implementa UserService {Nome da String Private; public String getName () {Return Name; } public void setName (nome da string) {this.name = name; } public void init () {System.out.println ("Initialize .."); } public void SayHello () {System.out.println ("Hello spring"+"/t"+nome); } public void Destory () {System.out.println ("Destroy .."); }}6. Defina arquivos de configuração específicos da mola
Defina o nome do ApplicationContext.xml, o local é SRC, o mesmo diretório do arquivo de log, importe as restrições correspondentes e injete a classe de implementação no arquivo de configuração. Basta começar com o início, use restrições de feijão
<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- Use a etiqueta do feijão 1. O valor do ID é único (deve escrever) 2. Nota: a classe é o caminho de classe de implementação, não uma interface (deve escrever) 3. O trabalho de inicialização antes do método do núcleo é executado (selecione Write). </ Bean> </ Beans>
7. Teste
public class Demo1 { /*** Way original* /@Test public void run () {// Crie a classe de implementação UserServiceImpl s = new UserserviceImpl (); s.setName ("Jaxiansen"); S.Sayhello (); } / *** Versão de fábrica antiga BeanFactory* Antiga fábrica não criará objetos de arquivo de configuração* / @Test public void run2 () {beanfactory factory = new XMLBeanFactory (new ClassPathResource ("ApplicationContext.xml")); UserService US = (UserService) Factory.getBean ("UserService"); us.sayhello (); } /*** Use o método do IOC da estrutura de primavera* Crie um servidor de inicialização na nova versão da fábrica para criar um objeto de arquivo de configuração, e não há necessidade de carregar a fábrica ao chamar novamente* /@Test public void run3 () {// Crie a fábrica e carregue o arquivo de configuração CORE (ClassThXMlApplicationContext é encontrado em SRC) ClassPathXMLApplicationContext ("ApplicationContext.xml"); // Obtenha o objeto do fábrica (valor de ID no arquivo de configuração, o polimorfismo é usado aqui) UserService USI = (UserService) AC.GetBean ("UserService"); // chamando o método do objeto para executar usi.sayhello (); } /*** Método de destruição de method de demonstração* O método de destruição do feijão não será executado automaticamente*, a menos que seja chamado automaticamente em scope = singleton ou em um contêiner da web, a função principal ou um caso de teste precisa ser chamado manualmente (precisa usar o método Close () de ClassPathXMLApplication antext)* /@Test Public Void Run4 () {) {) (ClassPathXMLApplicationContext é encontrado em SRC) ClassPathXMLApplicationContext AC = new ClassPathXMLApplicationContext ("ApplicationContext.xml"); // Obtenha o objeto do fábrica (valor de ID no arquivo de configuração, o polimorfismo é usado aqui) UserService USI = (UserService) AC.GetBean ("UserService"); // chamando o método do objeto para executar usi.sayhello (); // Classe de implementação ApplicationContext fornece um método próximo e a fábrica pode ser fechada e o método Destory-Method pode ser executado. }}A diferença entre fábricas antigas e novas fábricas
* Diferença entre BeanFactory e ApplicationContext
* BeanFactory - BeanFactory leva um carregamento preguiçoso, e o feijão será inicializado somente quando você obtiver pela primeira vez
* ApplicationContext - Ao carregar o ApplicationContext.xml, será criada uma instância específica do objeto Bean e algumas outras funções são fornecidas.
* Entrega de eventos
* Conjunto automático de feijão
* Implementações de contexto de várias camadas de aplicativos
Resumo: Esta é a demonstração mais básica, que configura a classe de implementação no arquivo de configuração da primavera. Cada vez que o servidor é iniciado, o arquivo de configuração será carregado, instanciando a classe de implementação.
1. O que é injeção de dependência?
A primavera pode efetivamente organizar objetos dos níveis de aplicação J2EE. Seja o objeto de ação da camada de controle, o objeto de serviço da camada de negócios ou o objeto DAO da camada de persistência, ele pode ser coordenado organicamente e executar sob o gerenciamento da primavera. A primavera organiza objetos de cada camada juntos de maneira vagamente acoplada. Os objetos de ação não precisam se preocupar com a implementação específica de objetos de serviço, os objetos de serviço não precisam se preocupar com a implementação específica de objetos de camada persistente e as chamadas para cada objeto de camada são completamente orientadas para interface. Quando o sistema precisar ser refatorado, a quantidade de reescrita de código será bastante reduzida. A injeção de dependência torna o feijão e o feijão organizado em arquivos de configuração, em vez de serem codificados. Entenda a injeção de dependência
A injeção de dependência e a inversão do controle são o mesmo conceito. O significado específico é: quando uma função (talvez uma instância Java, chamador) precisa da assistência de outra função (outra instância do Java, chamador), no processo de programação tradicional, o chamador é geralmente criado pelo chamador. Mas na primavera, o trabalho de criar o callee não é mais feito pelo chamador, por isso é chamado de inversão de controle; O trabalho de criar a instância da Callee geralmente é feito pelo recipiente de mola e depois injetado no chamador, por isso também é chamado de injeção de dependência.
Seja a injeção de dependência ou a inversão de controle, significa que a primavera adota uma maneira dinâmica e flexível de gerenciar vários objetos. As implementações específicas entre objetos são transparentes entre si.
2. O conceito de COI e DI
* COI - Inverso do controle, Controle Inversão, Inverta o direito de criação do objeto de primavera! !
* DI - Injeção de dependência, injeção de dependência, quando a estrutura da mola é responsável pela criação de objetos de feijão, injetando dinamicamente objetos de dependência no componente do feijão! !
3. Demo
Para variáveis de membro da classe, existem dois métodos de injeção comuns.
Injeção de método de conjunto de imóveis e injeção de método do construtor
Primeiro demonstrar o primeiro tipo: injeção do método do conjunto de propriedades
1) camada persistente
pacote com.clj.demo3; public class CustomerDaoimpl {public void save () {System.out.println ("Eu sou dao da camada de persistência"); }}2) camada de negócios
Nota: Neste momento, quero injetar a camada de persistência na camada de negócios e entregar o direito de criar a instância da camada de persistência à estrutura, a condição é que a camada de negócios deve fornecer os atributos do membro e definir métodos da camada de persistência.
pacote com.clj.demo3;/** * injeção de dependência injeta a camada dao na camada de serviço * @author administrador * */public class CustomerServiceImpl {// Fornece Zodiac, forneça método definido privado clientedaooImpl clientedao; public void setCustomerDao (CustomerDaoImpl CustomerDao) {this.customerdao = CustomerDao; } public void save () {System.out.println ("Eu sou o serviço ..."); // 1. Método original // novo CustomerDaoImpl (). Save (); //2.Spring IOC Método CustomerDao.Save (); }}3) Configuração do arquivo de configuração
<!-Demonstração Injeção de dependência-> <bean id = "CustomerDao"/> <bean id = "CustomerService"> <!-Injete o DAO na camada de serviço-> <Nome da propriedade = "CustomerDao" Ref = "CustomerDao"> </Property> </ Bean>
4) Teste
/** * Método de injeção de dependência da mola * Injete a camada DAO na camada de serviço */@test public void run2 () {// Crie a fábrica, carregue o arquivo de configuração e o cliente é criado, criando assim o cliente ApplicationContext Context = new ClassPathXMLApplicationContext ("ApplicationContext.xml"; CustomerServiceImpl csi = (CustomerServiceImpl) context.getBean ("CustomerService"); csi.save (); }O segundo tipo: injeção do método de construção
1) Classe Pojo e fornecem métodos construtores
pacote com.clj.demo4;/** * O método de injeção de demonstração * @Author Administrator * */public class Car1 {private string cname; preço duplo privado; public car1 (string cname, preço duplo) {super (); this.cname = cname; this.price = preço; } @Override public string tostring () {return "car1 [cname =" + cname + ", price =" + price + "]"; }}2) Configuração do arquivo de configuração
<!-demonstrar o método de injeção do método de construção-> <bean id = "car1"> <!-Write Method 1 <construtor-arg name = "cname" value = "bmw"/> <construtor-arg name = "price" Value = "400000"/>-> <!-Método 2-> <Fruttor- Index "=" 400000 "/>-> <!-! value = "400000"/> </i bean>
3) Teste
@Test public void run1 () {ApplicationContext AC = novo ClassPathXMLApplicationContext ("ApplicationContext.xml"); Car1 car = (car1) ac.getbean ("car1"); System.out.println (carro); }Extensão: a construção do método injeta um objeto em outro
1) Classe de Pojo: Objetivo: Injete o carro na coluna acima nos seres humanos e faça dele um dos atributos. Nesta classe, os atributos de membro do carro devem ser fornecidos e os métodos de construção parametrizados devem ser fornecidos.
pacote com.clj.demo4; public class Pessoa {private String Name; Car1 Car1 privado; pessoa pública (nome da string, car1 car1) {super (); this.name = nome; this.car1 = car1; } @Override public String tostring () {return "pessoa [name =" + name + ", car1 =" + car1 + "]"; }}2) arquivo de configuração
Er
4. Como injetar uma matriz de coleta
1) Defina a aula de Pojo
pacote com.clj.demo4; importar java.util.arrays; importar java.util.list; importar java.util.map; importar java.util.properties; importar java.util.set;/** ** * demonstre a maneira de definir a injeção * @author administrador * */public user {particular string string [** * Lista privada <String> Lista; Conjunto de conjunto privado <String>; mapa privado <string, string> mapa; Propriedades privadas 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 StarArrrs (String [] ARRRS) {this.arrs = ARRRS; } @Override public string tostring () {return "user [arrs =" + Arrays.toString (ARRS) + ", list =" + list + ", Sets =" + Sets + ", map =" + map + ", pro =" + pro + "]; }}2) arquivo de configuração
<!-Conjunto de injeção-> <bean id = "user"> <!-Array-> <propriedade name = "ars"> <list> <valor> Número1 </value> <Value> número2 </value> <Value> Número3 </Value> </List> </Property> <!-List Set-> <Nome = "List"> <List> <Value> </property> <!-set set-> <propriedade name = "Sets"> <Set> <Value> haha </value> <value> haha </value> </set> </propriedade> <!-map set-> <names name = "map"> <pap> <entradas key = "aa" "=" Rainus "/> <Dorp> key =" BB "BB") <propriedade name = "pro"> <ports> <props key = "nome de usuário"> root </pp> <prop key = "senha"> 123 </spo> </sports> </erouse> </sichean>
3) Teste
/ *** Coleção de injeção de teste*/ @Test public void run3 () {ApplicationContext AC = novo ClassPathXMLApplicationContext ("ApplicationContext.xml"); Usuário do usuário = (usuário) ac.getbean ("usuário"); System.out.println (usuário); }5. Como se desenvolver em módulos
Adicione a tag <Import> ao arquivo de configuração principal (assuma que um arquivo de configuração ApplicationContext2.xml é definido no pacote com.clj.test)
Er
1. Introdução
1). IMPORT JAR PACOTO
Além dos 6 pacotes anteriores, você também precisa de um pacote Spring-AOP para reproduzir anotação.
2). Camada de persistência e camada de implementação (as interfaces são ignoradas aqui)
Camada persistente
pacote com.clj.demo1; importar org.springframework.context.annotation.scope; importar org.springframework.tereotype.component; importar org.springframework.tereotype.repository;/** ** ** ** Administradores manuseados por userdaoimpl para iochuthuthuth * @** ** ** ** ** ** administradores manuseados por userdaoimpl to ioChutyuth * @** ** ** **. Userdao {@Override public void save () {System.out.println ("Salvar o cliente .."); }}Camada de negócios
pacote com.clj.demo1; importar javax.annotation.postConstruct; importar org.springframework.beans.factory.annotation.autowired; importar org.springframework.beans.factory.annotation.qualifier; importar.sPringFramework.BeanS.Factory.annotation.anTation.qualifier; importar.sPringFramework.BeanS.Factory.annOtation.annotation.notation.notation; org.springframework.tereotype.component; public class UserServiceImpl implementa usuários Service {@Override public void SayHello () {System.out.println ("Hello Spring"); }}3). Defina o arquivo de configuração
Neste momento, as restrições precisam adicionar restrições de contexto e adicionar varredura de componentes
<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 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 "> <!-Definições de Bean aqui-> <!-ScanTation Scann: Base-PAGE: Base-Package = "com.clj.demo1"/> </ Beans>
4) Adicione anotações à classe de implementação
/*** Anotação de componente, que pode ser usada para marcar a classe atual* semelhante a <bean id = "userService">* valor significa fornecer um alias para a classe*/@component (value = "userService") classe pública UserServiceImpl implementa UserService {// omitido}5) Escreva testes
/ *** Método de anotação*/ @Test public void run2 () {ApplicationContext AC = new ClassPathXMLApplicationContext ("ApplicationContext.xml"); UserService US = (UserService) AC.GetBean ("UserService"); us.sayhello (); }2. Sobre os atributos comuns de gerenciamento de feijões
1. @Component: Component. (agiu na classe) A anotação mais primitiva, não há problema em escrever isso para todas as classes que precisam de anotação, é geral
2. Três anotações derivadas do @component são fornecidas na primavera: (as funções são atualmente consistentes)
* @Controller - funciona na camada da web
* @Service - Atos no nível comercial
* @Repository - agindo na camada de persistência
* Nota: Essas três anotações destinam -se a tornar claro o objetivo da classe de anotação, e a primavera o aprimorará nas versões subsequentes.
3. Anotações para injeção de atributo (Nota: Ao usar a injeção de anotação, você não precisa fornecer um método definido)
* Se for um tipo normal de injeção, você pode usar a anotação de valor
* @Value - para injetar tipos normais
* Se o tipo de objeto injetado, use a seguinte anotação
* @Autowired - Por padrão, o tipo é montado automaticamente por tipo e não tem nada a ver com o nome da classe da classe injetada.
* Se você quiser injetar pelo nome
* @Qualifier - O uso forçado da injeção de nome deve ser usado com retenção automática, especifique o nome da classe e relacionado ao nome da classe injetada
* @Resource - equivalente a @Autowired e @qualifier
* Enfatizar: anotações fornecidas por Java
* O atributo usa o atributo de nome
4. Anotação do escopo do feijão
* ANOTADO COMO @SCOPE (VALUE = "Prototype"), que é usado na classe. Os valores são os seguintes:
* Singleton - Singleton, valor padrão
* Prototipo - vários casos
5. Configuração do ciclo de vida do feijão (entenda)
* A anotação é a seguinte:
* @PostConstruct-equivalente a init-method
* @Predestroy-equivalente ao Method
1. Demonstre anotação de objeto de atributo
Condição: Injetar atributos (nome) e objeto (userdaoImpl) na camada de negócios por digitalização.
1) Abra a camada de persistência para digitalizar a anotação
//@component (value = "userdao") universal classe anotação@repositório (value = "ud") public class userdaoimpl implementa Userdao {@Override public void save () {System.out.println ("salvar o cliente .."); }}2) A camada de negócios fornece anotações para atributos e objetos
pacote com.clj.demo1; importar javax.annotation.postConstruct; importar org.springframework.beans.factory.annotation.autowired; importar org.springframework.beans.factory.annotation.qualifier; importar.sPringFramework.BeanS.Factory.annotation.anTation.qualifier; importar.sPringFramework.BeanS.Factory.annOtation.annotation.notation.notation; org.springframework.stereotype.component;/** * Anotação de componentes, pode ser usada para marcar a classe atual * semelhante a <bean id = "userService"> * valor significa fornecer um alias à classe * /// @scope (value = "grototype") Múltiplos (singleType é uma única coluna) @COPENTE (Grototype ")) Múltiplos (singleType é uma única coluna) // Anotação de atributo: é equivalente a injetar a sequência especificada no atributo de nome. O método setName pode ser omitido sem escrever @value (value = "Jaxiansen") Nome da sequência privada; /** * Método de injeção de referência 1: Autowired () * Método de injeção de referência 2: Autowired () + Qualifier * Método de injeção de referência 3: @Resource (name = "userdao") o método Java, identificar a injeção por nome * // autowired () é montado automaticamente e injetado por tipo (desadvantagens: porque ele é o tipo de queda automaticamente, é assim que é montado e injetado por tipo (desade @Qualifier (value = "ud") // injeção pelo nome, deve ser usado com o AutoCired. Ambos podem especificar o UserDao Userdao privado da classe; // Observe que o valor no qualificador é o nome da anotação na parte superior do nome da classe UserDAOIMPL, ou você pode especificar o nome do ID do feijão no arquivo de configuração/*public void setName (nome da string) {this.name = name; }*/ @Override public void SayHello () {System.out.println ("Hello spring"+nome); userdao.save (); } // @PostConstruct Tag Anotation para inicialização no Action Lifecycle @PostConstruct public void init () {System.out.println ("Initialize ..."); }}3) O arquivo de configuração só precisa ser ativado para digitalizar todos os arquivos de configuração
<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 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 "> <!-Definições de Bean aqui-> <!-ScanTation Scann: Base-PAGE: Base-Package = "com.clj.demo1"/> </ Beans>
Nota: Quanto às coleções, é recomendável usar arquivos de configuração
2. O Spring Framework integra testes de unidade Junit
1) Adicione o pacote de dependência necessário teste de mola.jar
NOTA: O Myeclipes vem com seu próprio ambiente JUNIT, mas às vezes devido a problemas de versão, pode ser necessário um novo ambiente JUNIT. Aqui eu baixei um novo pacote JUB JUB JUNIT-4.9 Online. Se o Myeclipes for mais novo, você não precisa considerá -lo.
2) Escreva uma classe de teste e adicione anotações correspondentes
@Runwith e @ContextConfiguration (isso é usado para carregar o arquivo de configuração, porque o caminho padrão do Webroot é um diretório de primeiro nível, além disso, é para determinar que o SRC é um diretório de primeiro nível)
pacote com.clj.demo2; importar javax.annotation.resource; importar org.junit.test; importar org.junit.runner.runwith; importar org.springframework.test.context.ContextConfigaturation; importação Org.springFramework.test.test.Context.ContextConxtorn; com.clj.demo1.userService; @runwith (springjunit4classrunner.class) @ContextConfiguration ("ClassPath: ApplicationContext.xml") Public class Demo2 {@Resource (name = "Uservice") privado Uservice; @Test public void run1 () {userService.sayhello (); }}6. AOP da estrutura da primavera
1. O que é AOP
* Na indústria de software, AOP está a abreviação da programação orientada para aspectos, significando: programação de faceta, modularidade funcional
* AOP é um paradigma de programação, afiliado à categoria de trabalho suave, orientando os desenvolvedores a organizar estruturas de programas
* AOP foi proposta pela organização da AOP Alliance e formulou um conjunto de normas. A Spring introduziu as idéias da AOP na estrutura e deve cumprir as especificações da AOP Alliance.
* Uma tecnologia para alcançar a manutenção unificada das funções do programa por meio de pré -compilação e agentes dinâmicos durante o tempo de execução
* AOP é uma continuação do OOP, um tópico quente no desenvolvimento de software, uma parte importante da estrutura da primavera e um paradigma derivado de programação funcional.
* Usando a AOP, várias partes da lógica de negócios podem ser isoladas, reduzindo assim o acoplamento entre as partes da lógica de negócios, melhorando a reutilização do programa e melhorando a eficiência do desenvolvimento.
AOP adota um mecanismo de extração horizontal, substituindo o código repetitivo do sistema de herança vertical tradicional (monitoramento de desempenho, gerenciamento de transações, inspeção de segurança, cache)
2. Por que estudar AOP
* O programa pode ser aprimorado sem modificar o código -fonte! ! (Crie um proxy para um método fixo. Antes de acessar o método, insira o proxy primeiro. No proxy, você pode escrever mais funções para tornar o método mais poderoso e aprimorar o programa)
AOP: Programação orientada, modulariza tudo, cada módulo é relativamente independente, os módulos podem ser compartilhados (o mesmo) e diferentes são particularmente personalizados. Use isso em vez da programação vertical tradicional para melhorar a reutilização do programa
3. Implementação da AOP (Princípio da implementação)
A implementação do AOP inclui dois métodos de proxy <1> para implementar interfaces de classe: use o proxy dinâmico JDK <2> Interfaces de classe não implementadas: use CGLIB Proxy Dynamic
1. Implementar proxy dinâmico JDK
1) Defina a classe de implementação da interface da camada de persistência
pacote com.clj.demo3; interface pública userdao {public void save (); public void update ();} pacote com.clj.demo3; classe pública userdaoimpl implementa Userdao {@Override public void save () {System.out.println ("Salvar usuário"); } @Override public void update () {System.out.println ("Modify User"); }}2) Definir classe de ferramenta de proxy dinâmica JDK
Esta classe de ferramenta adiciona algumas funções ao executar o método de salvar camada de persistência e, no desenvolvimento, é necessário aprimorar um determinado método sem alterar o código -fonte
pacote com.clj.demo3; importar java.lang.reflect.invocationHandler; importar java.lang.reflect.method; importar java.lang.reflect.proxy;/** * gere objetos de proxy em jdk (demonstram os princípios do AOPT) * @author * * * * * */gettyTraty (** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Userdao dao) {// use a classe proxy para gerar objetos proxy userdao proxy = (userdao) proxy.newproxyInstance (Dao.getClass (). Invocar (proxy do objeto, método do método, objeto [] args) lança arremesso {// proxy representa o método de proxy // de proxy atual executado pelo objeto atual // Args parâmetros encapsulados // let the Class Salvar ou atualizar o método Executar normalmente se (salvar ".Equals (Method.getName ()); método.invoke (dao, args); Retornar proxy; }}3) Teste
pacote com.clj.demo3; importar org.junit.test; public class Demo1 {@test public void run1 () {// obtenha o objeto de destino Userdao dao = new userdaoimpl (); Dao.save (); Dao.Update (); System.out.println ("=================================================================== ========================================================================================== Use a classe de ferramenta para obter o objeto proxy Userdao proxy = myProxyutils.getProxy (dao);2. Implementar a tecnologia CGLIB
1) Defina a camada de persistência, não há interface neste momento
pacote com.clj.demo4; classe pública bookdaoimpl {public void save () {System.out.println ("salvar livro"); } public void update () {System.out.println ("Modify Book"); }}2) Escreva aulas de ferramentas
pacote com.clj.demo4; importar java.lang.reflect.method; importar org.springframework.cglib.proxy.enhancer; importar org.springframework.cglib.proxy.methintercept; Método proxy * @Author Administrator * */public classe mycglabils {/** * Gere um objeto Proxy usando o método cglib * @return */public static bookdaoimpl getProxy () {intensificador intensificador = new intensancer (); // Defina a classe pai intensificadora.SetSuperclass (bookdaoimpl.class); // defina a função de retorno de chamada aprimor.setCallback (new MetodIntercept () {@Override Public Object Intercept (object Obj, método do método, objeto [] objs, métodProxy MethodProxy) lança throwable {if (method.getName (). Equals (Salve ") {System.out.println (" i sav "i sav" i sav "i savn"; } retornar métodProxy.invokesuper (obj, objs); // é o método executado}}); // gerar o proxy objeto bookdaoimpl proxy = (bookdaoImpl) intensificador.create (); Retornar proxy; }}3) Escreva aulas de teste
pacote com.clj.demo4; importar org.junit.test; public class Demo1 {@test public void run1 () {// Target Object bookdaoimpl Dao = new bookdaoimpl (); Dao.save (); Dao.Update (); System.out.println ("===============================); BookdaoImpl proxy = mycglutils.getproxy (); proxy.save (); proxy.update ();}}3. Desenvolvimento de AOP da primavera com base no aspecto (método de arquivo de configuração)
1) Implante o ambiente e importe o pacote JAR correspondente
2) Crie arquivos de configuração e introduza restrições de AOP
<Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-nstance" xmlns:aop="http://www.springframework.org/schema/aop" 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/aop/aop/sring-apop.xsd "
3) Crie interfaces e implemente classes
pacote com.clj.demo5; interface pública CustomerDao {public void save (); public void update ();} pacote com.clj.demo5;/** * Use o arquivo de configuração para interpretar aOP * @Author Administrator * */public class CustomerDaoImpl implementa CustomerDao {@Override public void save () {// simular exceção // int a = 10/0; System.out.println ("Salvar o cliente"); } @Override public void update () {// TODO Method Auto-Gerated Stub System.out.println ("Atualizado o Cliente"); }}4) Defina a aula de faceta
pacote com.clj.demo5; importar org.aspectj.lang.proecedingJoinPoint;/** * Classe de faceta: ponto de entrada + notificação * @Author Administrator * */public class myaspectxml {/** ** ** * logs (aprimoramento específico) */public void Log () {System.out.println ("Log" Log ") } / ** * O método é executado com sucesso ou as exceções serão executadas * / public void após () {System.out.println ("Notificação final"); } /*** Depois que o método for executado, a notificação post é executada. Se ocorrer uma exceção no programa, a notificação post não será executada */ public void após o return () {System.out.println ("Post Notification"); } / ** * Depois que o método for executado, se houver uma exceção, a notificação de exceção será executada * / public void depois de arremessamento () {System.out.println ("Notificação da exceção"); } /*** Notificação surround: A notificação é feita antes e depois que o método é executado. * Por padrão, o método do objeto de destino não pode ser executado e o objeto de destino precisa ser executado manualmente */ public void em torno (ProceingJoinPoint Jun Junpoint) {System.out.println ("Notificação de Wrap 1"); // Deixe manualmente o método do objeto de destino Executar Try {junçãoPoint.proeced (); } catch (throwable e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } System.out.println ("Notificação de Wrap 2"); }}5) Injetar classes de implementação e faceta
<?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{ // 方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类private 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{ //方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } //方式二:持久层继承JdbcDaoSupport,它里面封转了模板类,配置文件持久层无需注入模板类,也不需要配置模板类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{ //采用的是配置文件注入方式,必须提供set方法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{ //方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } //方式二:持久层继承JdbcDaoSupport,它里面封转了模板类,配置文件持久层无需注入模板类,也不需要配置模板类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{ //采用的是配置文件注入方式,必须提供set方法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;//在当前类加此注解表示当前类所有的全部都有事务@Transactionalpublic class AccountServiceImpl implements AccountService{ //采用的是配置文件注入方式,必须提供set方法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{ //方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } //方式二:持久层继承JdbcDaoSupport,它里面封转了模板类,配置文件持久层无需注入模板类,也不需要配置模板类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); }}O exposto acima é todo o conteúdo deste artigo. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.