Spring學習總結----
1、導入Spring必須的jar包
2、簡單示例入門注入一個User
1.編寫User實體類java
package test.Spring.helloworld; import java.util.List; import java.util.Map; public class User { @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } private int id; private String name; }
2.編寫Spring配置文件,類型爲xml,文件名能夠自定義mysql
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > <bean id="User" class="test.Spring.helloworld.User"> <property name="id" value="1"></property> <property name="name" value="jayjay"></property> </bean> </beans>
3.利用Spring容器建立託管對象Userspring
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml"); User u = (User)context.getBean("User"); System.out.println(u);
3、Bean的配置深刻
1.bean引用其餘beansql
實體類示例:數據庫
package test.Spring.helloworld; public class HelloWorld { public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "HelloWorld [name=" + name + ", user=" + user + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; private User user; public HelloWorld(){ } public HelloWorld(String name){ this.name = name; } }
配置示例:express
<!-- reference other bean --> <bean id="HelloWorld" class="test.Spring.helloworld.HelloWorld"> <!-- <property name="name" value="spring1"></property> --> <constructor-arg value="spring2" type="java.lang.String"></constructor-arg> <property name="user"> <ref bean="User"/> </property> </bean>
調用方法依然是根據bean中的id緩存
2.集合bean配置session
實體類示例:app
package test.Spring.helloworld; import java.util.List; import java.util.Map; public class User { public Map<String, Integer> getMap() { return map; } public void setMap(Map<String, Integer> map) { this.map = map; } public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", list=" + list + ", map=" + map + "]"; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } private int id; private String name; private List<String> list; private Map<String,Integer> map; }
配置示例:ide
<!-- Configure the list bean --> <bean id="testList" class="test.Spring.helloworld.User"> <property name="list"> <list> <value>list1</value> <value>list2</value> <value>list3</value> </list> </property> </bean> <!-- configure the map --> <bean id="testMap" class="test.Spring.helloworld.User"> <property name="map"> <map> <entry key="first" value="1"></entry> <entry key="second" value="2"></entry> <entry key="third" value="3"></entry> </map> </property> </bean>
3.Properties類型的bean
實體類示例:
package test.Spring.helloworld; import java.util.Properties; public class DataSource { @Override public String toString() { return "Properties [properties=" + properties + "]"; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } private Properties properties; }
配置示例:
<!-- configure the properties --> <bean id="dataSource1" class="test.Spring.helloworld.DataSource"> <property name="properties"> <props> <prop key="user">root</prop> <prop key="password">1234</prop> <prop key="jdbcUrl">jdbc:mysql:///test</prop> <prop key="driverClass">com.mysql.jdbc.Driver</prop> </props> </property> </bean>
4.使用Util定義引用其餘bean的公共集合
須要先在xml導入命名空間
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd" xmlns:util="http://www.springframework.org/schema/util" > </beans>
集合以及調用的xml配置
<!-- if properties of collection are beans --> <util:list id="users"> <ref bean="User"/> <ref bean="User"/> <ref bean="User"/> </util:list> <bean id="Users" class="test.Spring.helloworld.Users"> <property name="list"> <ref bean="users"/> </property> </bean>
5.使用p簡化bean的屬性賦值
首先,導入p的命名空間
xmlns:p="http://www.springframework.org/schema/p"
實體類實例:
package test.Spring.helloworld; import java.util.List; import java.util.Map; public class User { @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } private int id; private String name; }
配置示例:
<!-- use p to write the bean quickly and conveniently --> <bean id="User1" class="test.Spring.helloworld.User" p:id="2" p:name="jayjay2" />
6.abstract模板bean
設置abstract=true代表此bean是模板bean,爲其餘bean提供屬性值模板
<!-- template bean --> <bean abstract="true" id="template" p:id="50" p:name="fromTemplate"></bean> <bean id="User2" parent="template" class="test.Spring.helloworld.User"></bean>
7.單例bean和原型bean
<!-- use scope to build singleton/prototype bean --> <bean id="User3" parent="template" scope="singleton" class="test.Spring.helloworld.User"></bean> <bean id="User4" parent="template" scope="prototype" class="test.Spring.helloworld.User"></bean>
singleton:此bean爲單例,在context建立時已經建立,而且只有一個實例。
prototype:當須要時建立實例。
8.靜態工廠方法配置bean
靜態工廠類示例:
package test.Spring.FactoryBean; import java.util.HashMap; import java.util.Map; public class StaticFactoryMethod { public static Map<String,Person> map = new HashMap<String,Person>(); static { map.put("first", new Person(1,"jayjay1")); map.put("second", new Person(2,"jayjay2")); } public static Person getPerson(String key){ return map.get(key); } }
配置示例:
<!-- static factory method --> <bean id="person" factory-method="getPerson" class="test.Spring.FactoryBean.StaticFactoryMethod"> <constructor-arg value="first" type="java.lang.String"></constructor-arg> </bean>
9.實例工廠方法配置bean
工廠類示例:
package test.Spring.FactoryBean; import java.util.HashMap; import java.util.Map; public class InstanceFactoryMethod { public static Map<String,Person> map = new HashMap<String,Person>(); static { map.put("first", new Person(1,"jayjay1")); map.put("second", new Person(2,"jayjay2")); } public Person getPerson(String key){ return map.get(key); } }
配置示例:
<!-- instance factory method --> <bean id="InstanceFactoryMethod" class="test.Spring.FactoryBean.InstanceFactoryMethod"></bean> <bean id="person1" factory-bean="InstanceFactoryMethod" factory-method="getPerson"> <constructor-arg value="second"></constructor-arg> </bean>
10.經過實現FactoryBean完成bean的配置
須要對FactoryBean接口的3個方法進行適當重寫
PersonFactoryBean類示例:
package test.Spring.FactoryBean; import org.springframework.beans.factory.FactoryBean; public class PersonFactoryBean implements FactoryBean<Person>{ public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } private int id; private String name; @Override public Person getObject() throws Exception { // TODO Auto-generated method stub return new Person(id,name); } @Override public Class<?> getObjectType() { // TODO Auto-generated method stub return Person.class; } @Override public boolean isSingleton() { // TODO Auto-generated method stub return false; } }
配置示例:
<!-- use factory bean to get a instance --> <bean id="person2" class="test.Spring.FactoryBean.PersonFactoryBean"> <property name="id" value="3"></property> <property name="name" value="FactoryBean"></property> </bean>
4、經過註解配置bean
加上註解的類會被Spring容器管理
@Component
標註於通用實體類
@Controller
標註於Controller/Action
@Service
標註於Service
@Respository
標註於RespositoryImpl/DaoImlp
@Autowired
依據類型自動裝配
@Qualifier
指定自動裝載的bean的name
1.在Spring配置文件中導入context命名空間,並加入
<context:component-scan base-package="test.Spring.Annotation"></context:component-scan>
表示Spring將掃描test.Spring.Annotation及其子包中全部java文件,並將帶有註解的類加入Spring容器進行管理。
例如:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" xmlns:context="http://www.springframework.org/schema/context"> <context:component-scan base-package="test.Spring.Annotation"></context:component-scan> </beans>
2.模擬三層,並用Spring註解方式注入
項目結構:
Person實體類
package test.Spring.Annotation; import org.springframework.stereotype.Component; @Component public class Person { @Override public String toString() { return "Person [id=" + id + ", name=" + name + "]"; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } private int id; private String name; }
PersonController
package test.Spring.Annotation.Controller; import org.springframework.stereotype.Controller; @Controller public class PersonController { public void excute(){ System.out.println("PersonController.excute()..."); } }
PersonService
package test.Spring.Annotation.Service; import org.springframework.stereotype.Service; @Service public class PersonService { public void add(){ System.out.println("PersonService.add()..."); } }
PersonRepository接口
package test.Spring.Annotation.Repository; public interface PersonRepository { void add(); }
PersonRepositoryImpl接口實現類
package test.Spring.Annotation.Repository; import org.springframework.stereotype.Repository; @Repository public class PersonRepositoryImpl implements PersonRepository { @Override public void add() { System.out.println("PersonRepositoryImpl.add()..."); } }
Main類中測試
package test.Spring.Annotation; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import test.Spring.Annotation.Controller.PersonController; import test.Spring.Annotation.Repository.PersonRepository; import test.Spring.Annotation.Service.PersonService; public class Main { public static void main(String[] args) { ApplicationContext context =new ClassPathXmlApplicationContext("applicationContextForAnnotation.xml"); //inject the common bean System.out.println(context.getBean("testAutowired")); //inject the repository PersonRepository pr = (PersonRepository)context.getBean("personRepositoryImpl"); pr.add(); //inject the controller PersonController pc = (PersonController)context.getBean("personController"); pc.excute(); //inject the service PersonService ps = (PersonService)context.getBean("personService"); ps.add(); } }
3.泛型三層的注入
Spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd " xmlns:context="http://www.springframework.org/schema/context" > <context:component-scan base-package="test.Spring.Generic.di"></context:component-scan> </beans>
BaseRespository
package test.Spring.Generic.di; public class BaseRepository<T> { public void save() { System.out.println("repository.save()..."); } }
PersonRepository
package test.Spring.Generic.di; public interface PersonRespository { void save(); }
PersonRepositoryImpl
繼承BaseRepository就不須要再寫一次save方法,且同時實現了PersonRepository接口
package test.Spring.Generic.di; import org.springframework.stereotype.Repository; import test.Spring.Annotation.Person; @Repository public class PersonRespositoryImpl extends BaseRepository<Person> implements PersonRespository { }
BaseService對Dao進行自動裝配,子類繼承後裝配的是子類Respository
package test.Spring.Generic.di; import org.springframework.beans.factory.annotation.Autowired; public class BaseService<T> { @Autowired protected BaseRepository<T> baseRespository; public void save(){ System.out.println("service.save()..."); System.out.println(baseRespository); } }
PersonService繼承了BaseService,就不須要再寫實現save方法,定義Repository字段了
package test.Spring.Generic.di; import org.springframework.stereotype.Service; import test.Spring.Annotation.Person; @Service public class PersonService extends BaseService<Person>{ }
Main類中調用
package test.Spring.Generic.di; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context =new ClassPathXmlApplicationContext("applicationContextForGeneric.xml"); PersonService ps = (PersonService)context.getBean("personService"); ps.save(); } }
輸出爲
第二句說明調用的是繼承BaseService的PersonService拿到的Respository是PersonRepositoryImpl,說明泛型注入成功。
10、使用SpringAOP完成簡單的程序
1.導入SpringAOP所需jar包
2.編寫spring的配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.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 " xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" > <!-- configure the package for spring to scan --> <context:component-scan base-package="test.Spring.AOP" /> <!-- make the aspectj annotation to be used --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
3.建立一個HelloWord接口以及它的實現類HelloWordImpl
public interface HelloWord { public int sayHello(int num); }
@Component public class HelloWordImpl implements HelloWord{ public int sayHello(int num){ System.out.println("hello word"); return 100/num; } }
4.SpringAOP註釋的類型有5種
@Before 前置通知 在方法執行前執行
@After 後置通知 在方法執行後執行
@AfterThrowing 異常通知 在方法拋出異常以後執行
@AfterReturning 返回通知 在方法返回結果以後執行
@Around 環繞通知 環繞着方法執行
5.建立一個切面類(包含@Before @After @AfterThrowing @AfterReturning)
@Component @Aspect public class HelloWordAspect { @Before(value="execution(* test.Spring.AOP.HelloWord.sayHello(..))") public void beforeMethod(JoinPoint jp){ String methodName = jp.getSignature().getName(); System.out.println(methodName); System.out.println("before method execute,args are "+Arrays.toString(jp.getArgs())); } @After("execution(* test.Spring.AOP.HelloWord.sayHello(..))") public void afterMethod(JoinPoint jp){ System.out.println("after method execute,args are "+Arrays.toString(jp.getArgs())); } @AfterThrowing(value="execution(* test.Spring.AOP.HelloWord.sayHello(..))",throwing="ex") public void afterThrow(Exception ex){ System.out.println("afterThrow"+ex.getMessage()); } @AfterReturning(value="execution(* test.Spring.AOP.HelloWord.sayHello(..))",returning="result") public void afterReturn(Object result){ System.out.println("the result is "+result); } }
6.在主函數調用
public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextForAOP.xml"); HelloWord hw = (HelloWord) context.getBean("helloWordImpl"); hw.sayHello(10); } }
7.調用結果
結果說明,在sayHello方法是被Spring代理執行了,執行先後加上了一些切面類中定義的信息。
8.使用Around環繞通知切面類實現相似效果
@Component @Aspect public class HelloWordAspectAround { @Around(value="execution(* test.Spring.AOP.HelloWord.sayHello(..)))") public Object aroundMethod(ProceedingJoinPoint pjp){ Object result = null; String methodName = pjp.getSignature().getName(); try { result = pjp.proceed(); System.out.println("the result is "+result); } catch (Throwable e) { System.out.println("Exception occurs : "+e.getMessage()); throw new RuntimeException(e); } System.out.println(methodName+" end"); return result; } }
11、SpringAOP整合Hibernate並使用事務(模擬買書的過程)
1.內容準備
①.編寫實體類
Book
public class Book { public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } private int id; private String name; private int price; private int count; }
Customer
public class Customer { public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } private int id; private String name; private int balance; }
②.編寫實體類映射文件
<hibernate-mapping package="springaop.model"> <class name="Book" table="t_book"> <id name="id" type="int" column="id" > <generator class="native"></generator> </id> <property name="name" type="string" column="name"/> <property name="price" type="int" column="price"/> <property name="count" type="int" column="count"/> </class> </hibernate-mapping>
<hibernate-mapping package="springaop.model"> <class name="Customer" table="t_customer"> <id name="id" type="int" column="id" > <generator class="native"></generator> </id> <property name="name" type="string" column="name"/> <property name="balance" type="int" column="balance"/> </class> </hibernate-mapping>
③.編寫dao及daoImpl
public interface ShopRepository { public int findBookPriceByBookName(String name); public void updateBookCount(String name); public void updateUserBalance(String name,int price); }
@Repository public class ShopRepositoryImpl implements ShopRepository{ @Autowired private SessionFactory sessionFactory; private Session getSession(){ return sessionFactory.getCurrentSession(); } @Override public int findBookPriceByBookName(String name) { String sql = "select b.price from Book b where b.name=?"; Query query = getSession().createQuery(sql).setString(0, name); return (Integer)query.uniqueResult(); } @Override public void updateBookCount(String name) { String sql1 = "select b.count from Book b where b.name=?"; Query query = getSession().createQuery(sql1).setString(0,name); int count = (int)query.uniqueResult(); if(count<=0){ throw new RuntimeException("庫存不足"); } String sql2 = "update Book b set b.count=b.count-1 where b.name=?"; getSession().createQuery(sql2).setString(0,name).executeUpdate(); } @Override public void updateUserBalance(String name, int price) { String sql1 = "select c.balance from Customer c where c.name=?"; Query query = getSession().createQuery(sql1).setString(0,name); int count = (int)query.uniqueResult(); if(count-price<0){ throw new RuntimeException("餘額不足"); } String sql2 = "update Customer c set c.balance=c.balance-? where c.name=?"; getSession().createQuery(sql2).setInteger(0, price).setString(1,name).executeUpdate(); } }
④.編寫service及serviceImpl
public interface ShopService { public void shop(String bookName,String username); }
@Service public class ShopServiceImpl implements ShopService{ @Autowired private ShopRepository sr; @Override public void shop(String bookName, String username) { int price = sr.findBookPriceByBookName(bookName); sr.updateUserBalance(username, price); sr.updateBookCount(bookName); } }
2.加入Hibernate
①.添加hibernate必須的jar包
②.添加hibernate.cfg.xml
<hibernate-configuration> <session-factory> <!-- 配置hibernate的基本屬性 --> <!-- 1.數據源的配置,配置到SpringIOC中,此處不須要再進行配置 --> <!-- 2.關聯實體的映射文件 .hbm.xml文件也在IOC容器配置SessionFactory實例時配置 --> <!-- 3.配置hibernate的基本屬性 方言、sql顯示及格式化、數據庫表生成策略、二級緩存--> <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">update</property> <!-- 配置hibernate二級緩存相關 --> </session-factory> </hibernate-configuration>
3.加入Spring
①.導入Spring必須的jar包
②.配置Spring的applicationContext.xml及db.properties文件
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd " xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" > <!-- 配置Spring掃描的包 --> <context:component-scan base-package="springaop"></context:component-scan> <!-- 配置數據源 --> <!-- 導入資源文件 --> <context:property-placeholder location="classpath:db.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property> <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property> </bean> <!-- 配置Hibernete的SessionFactory實例 --> <!-- 經過配置Spring提供的LcalSessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> <property name="mappingLocations" value="classpath:springaop/model/*.hbm.xml"></property> </bean> <!-- 配置Spring的聲明式事務 --> <!-- 1.配置事務管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 2.配置事務屬性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- 3.配置事務切點,並把切點和事務關聯起來, --> <aop:config> <aop:pointcut expression="execution(* springaop.service.*.*(..))" id="txPointcut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config> </beans>
jdbc.user=root
jdbc.password=1234
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///test
jdbc.initialPoolSize=5
jdbc.maxPoolSize=10
4.運行測試
public class test { private ApplicationContext context = null; private ShopService ss = null; { context = new ClassPathXmlApplicationContext("applicationContext.xml"); ss= context.getBean(ShopService.class); } @Test public void test() throws SQLException{ DataSource ds = context.getBean(DataSource.class); System.out.println(ds.getConnection()); } @Test public void test1(){ ss.shop("Java", "jayjay"); } @Test public void test3(){ ss.shop("C", "jayjay"); } }
當錢不夠的時候,會拋出異常「餘額不足」,而且事務回滾;當錢足夠時,正常執行。