大部分狀況下,使用Spring配置依賴注入時,都是使用註解來進行配置,由於註解比xml要方便和簡單。不過相似於數據源對象這種配置信息容易變動的對象除外,這種對象使用xml文件來進行配置會更適合,方便於在外部進行修改,而不須要打開代碼來進行修改。java
接下來簡單介紹一下註解的配置方式,首先要讓Spring支持註解,編輯Spring配置文件內容以下: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" xmlns:p="http://www.springframework.org/schema/p" 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 "> <!-- 讓spring支持註解 --> <context:annotation-config/> <!-- 指定哪些包下的類受可讓Spring經過註解來管理 --> <context:component-scan base-package="org.zero01"/> </beans>
經過註解配置來讓Spring幫咱們建立對象,Student類代碼以下:spring
package org.zero01; import org.springframework.stereotype.Component; // 加上這個註解表示該類受到Spring的管理,註解的值爲該類的id,該註解的做用至關於xml中的bean標籤 @Component("stu") public class Student { ...
測試代碼:sql
package org.zero01; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); // 一樣的經過配置的id得到實例對象 Student stu1 = (Student) app.getBean("stu"); Student stu2 = (Student) app.getBean("stu"); // 默認都是單例對象 if (stu1 == stu2) { System.out.println("單例對象"); }else{ System.out.println("非單例對象"); } } }
運行結果:json
單例對象
使用註解時能夠不配置id值,直接寫上 @Component 也行:bash
package org.zero01; import org.springframework.stereotype.Component; @Component public class Student { ...
而後經過該類的class來獲取實例對象:app
Student stu1 = app.getBean(Student.class);
可是這種方式的靈活性沒有使用id值的方式好,由於字符串是能夠經過變量改變的,而這種使用class的方式至關因而寫死在代碼上了。ide
若是不但願從容器裏取出來的不是單例對象的話,可使用 @Scope 註解來配置指定使用原型模式,須要配置屬性的值可使用 @Value 註解進行配置,例如:測試
package org.zero01; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.context.annotation.Scope; @Component("stu") @Scope(value = "prototype") // 取值與xml中的scope屬性是同樣的 public class Student { @Value("小明") private String name; @Value("15") private int age; @Value("南京") private String address; ...
測試代碼:ui
package org.zero01; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); Student stu1 = app.getBean(Student.class); Student stu2 = app.getBean(Student.class); if (stu1 == stu2) { System.out.println("單例對象"); }else{ System.out.println("非單例對象"); } System.out.println(stu1.getName()); System.out.println(stu1.getAge()); System.out.println(stu1.getAddress()); } }
運行結果:
非單例對象 小明 15 南京
注:咱們能夠將 @Value 註解寫在屬性的setter方法上,和寫在屬性上的做用是同樣的。
若是須要注入自建類型,有兩個註解能夠作到,分別是 @Resource 和 @Autowired,可是要想經過這兩個註解來配置依賴注入,被注入的對象須要寫上 @Component 註解:
package org.zero01; import org.springframework.stereotype.Component; @Component("phone") public class Phone { } package org.zero01; import org.springframework.stereotype.Component; @Component("dog") public class Dog { }
而後纔可使用 @Resource 和 @Autowired 註解配置依賴注入,Student類代碼:
package org.zero01; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.context.annotation.Scope; import javax.annotation.Resource; @Component("stu") @Scope(value = "prototype") public class Student { @Value("小明") private String name; @Value("15") private int age; @Value("南京") private String address; @Resource private Dog dog; @Autowired private Phone phone; ...
測試代碼:
package org.zero01; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); Student stu1 = app.getBean(Student.class); System.out.println(stu1.getName()); System.out.println(stu1.getAge()); System.out.println(stu1.getAddress()); System.out.println(stu1.getDog()); System.out.println(stu1.getPhone()); } }
運行結果:
小明 15 南京 org.zero01.Dog@47db50c5 org.zero01.Phone@5c072e3f
@Autowired 和 @Resource的區別簡述:
@Autowired(required=false)
,也可使用名稱裝配,配合 @Qualifier 註解。使用以上介紹到的註解作一個簡單的增刪查改小例題:
pom.xml文件配置以下:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.14.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20160810</version> </dependency> </dependencies>
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" xmlns:p="http://www.springframework.org/schema/p" 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 "> <!-- 讓spring支持註解 --> <context:annotation-config/> <!-- 指定哪些包下的類受可讓Spring經過註解來管理 --> <context:component-scan base-package="org.zero01"/> <!-- 配置數據源對象 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" p:driverClass="com.mysql.jdbc.Driver" p:jdbcUrl="jdbc:mysql:///school" p:user="root" p:password="your_password" p:maxPoolSize="10" p:minPoolSize="1" p:loginTimeout="2000" /> </beans>
首先是接口代碼:
package org.zero01.dao; import org.zero01.pojo.Student; import java.util.List; public interface DAO { public int insert(Student student) throws Exception; public int delete(int sid) throws Exception; public List<Student> selectAll() throws Exception; public int update(Student student) throws Exception; } package org.zero01.service; import org.zero01.pojo.Student; import java.util.List; public interface Service { public int enterSchool(Student student); public int dropOut(int sid); public List<Student> getStudents(); public int updateData(Student student); } package org.zero01.view; import org.zero01.pojo.Student; import java.util.List; public interface View { public int enterSchool(Student student); public int dropOut(int sid); public List<Student> getStudents(); public int updateData(Student student); }
而後是具體的實現類代碼,StudentDAO類:
package org.zero01.dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.zero01.pojo.Student; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @Component("stuDAO") public class StudentDAO implements DAO { @Autowired private DataSource dataSource; public int insert(Student student) throws Exception { Connection connection = null; try { connection = dataSource.getConnection(); String sql = "INSERT INTO student(sname,age,sex,address) VALUES (?,?,?,?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, student.getSname()); preparedStatement.setInt(2, student.getAge()); preparedStatement.setString(3, student.getSex()); preparedStatement.setString(4, student.getAddress()); int row = preparedStatement.executeUpdate(); if (row > 0) { return row; } } catch (SQLException e) { e.printStackTrace(); } finally { connection.close(); } return 0; } public int delete(int sid) throws Exception { Connection connection = null; try { connection = dataSource.getConnection(); String sql = "DELETE FROM student WHERE sid=?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1, sid); int row = preparedStatement.executeUpdate(); if (row > 0) { return row; } } catch (SQLException e) { e.printStackTrace(); } finally { connection.close(); } return 0; } public List<Student> selectAll() throws Exception { Connection connection = null; try { connection = dataSource.getConnection(); String sql = "select * from student"; PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery(); List<Student> students = new ArrayList<Student>(); while (resultSet.next()) { Student student = new Student(); student.setSid(resultSet.getInt("sid")); student.setSname(resultSet.getString("sname")); student.setSex(resultSet.getString("sex")); student.setAddress(resultSet.getString("address")); students.add(student); } return students; } catch (SQLException e) { e.printStackTrace(); } finally { connection.close(); } return null; } public int update(Student student) throws Exception { Connection connection = null; try { connection = dataSource.getConnection(); String sql = "UPDATE student SET sname=?,age=?,sex=?,address=? WHERE sid=?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, student.getSname()); preparedStatement.setInt(2, student.getAge()); preparedStatement.setString(3, student.getSex()); preparedStatement.setString(4, student.getAddress()); preparedStatement.setInt(5, student.getSid()); int row = preparedStatement.executeUpdate(); if (row > 0) { return row; } } catch (SQLException e) { e.printStackTrace(); } finally { connection.close(); } return 0; } }
SchoolService代碼:
package org.zero01.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.zero01.dao.DAO; import org.zero01.pojo.Student; import java.util.List; @Component("schoolService") public class SchoolService implements Service { @Autowired private DAO dao; public int enterSchool(Student student) { try { return dao.insert(student); } catch (Exception e) { e.printStackTrace(); } return 0; } public int dropOut(int sid) { try { return dao.delete(sid); } catch (Exception e) { e.printStackTrace(); } return 0; } public List<Student> getStudents() { try { return dao.selectAll(); } catch (Exception e) { e.printStackTrace(); } return null; } public int updateData(Student student) { try { return dao.update(student); } catch (Exception e) { e.printStackTrace(); } return 0; } }
SchoolAction代碼:
package org.zero01.view; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.zero01.pojo.Student; import org.zero01.service.Service; import java.util.List; @Component("stuAction") public class SchoolAction implements View { @Autowired private Service schoolService; public int enterSchool(Student student) { return schoolService.enterSchool(student); } public int dropOut(int sid) { return schoolService.dropOut(sid); } public List<Student> getStudents() { return schoolService.getStudents(); } public int updateData(Student student) { return schoolService.updateData(student); } }
從以上的代碼能夠看到,咱們沒有在哪個類裏寫了關於任何實例化對象的代碼,而是把實例化這項工做交給Spring容器去幫咱們完成,這樣每一個類都不須要去管理、維護本身的依賴對象,只須要完成本身業務代碼便可,這樣弱化了類與類之間的依賴,讓代碼的複雜度下降,每一個類都只須要維護本身的業務代碼便可,這是Spring的IOC模塊給咱們帶來的好處。並且每一個類都依賴的是接口,而不是具體的實現類,符合依賴倒轉原則,不會致使代碼緊耦合,當具體的實現類被替換時,不會影響到其餘類。
測試代碼:
package org.zero01; import org.json.JSONObject; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.zero01.view.View; import org.zero01.pojo.Student; import java.util.HashMap; import java.util.Map; public class Test { public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); View view = (View) app.getBean("stuAction"); Student student = (Student) app.getBean("student"); System.out.println("enterSchool() 影響行數:" + view.enterSchool(student)); System.out.println("dropOut() 影響行數:" + view.dropOut(25)); Map<String, Object> map = new HashMap<String, Object>(); map.put("studentList", view.getStudents()); map.put("length", view.getStudents().size()); System.out.println(new JSONObject(map)); student.setSname("小剛"); student.setAddress("長沙"); student.setAge(18); student.setSid(29); System.out.println("updateData() 影響行數:" + view.updateData(student)); } }
運行結果:
enterSchool() 影響行數:1 dropOut() 影響行數:1 { "studentList": [ { "address": "南京", "sname": "小明", "sex": "男", "age": 0, "sid": 26 }, { "address": "南京", "sname": "小明", "sex": "男", "age": 0, "sid": 27 }, { "address": "南京", "sname": "小明", "sex": "男", "age": 0, "sid": 28 }, { "address": "南京", "sname": "小明", "sex": "男", "age": 0, "sid": 29 }, { "address": "南京", "sname": "小明", "sex": "男", "age": 0, "sid": 30 }, { "address": "南京", "sname": "小明", "sex": "男", "age": 0, "sid": 31 } ], "length": 6 } updateData() 影響行數:1