Copy from: http://moira-god.javaeye.com/blog/585631
Spring's philosophy is to add Java objects to the framework without affecting the design of Java objects. Let's take a look at the working principle of Spring and see how Spring does not affect Java objects.
The EJB framework uses an aggressive (Invasive) method to design objects. It requires you to add code that complies with the EJB specifications in the design. Some lightweight COP frameworks, such as aveon, also require that objects must comply with certain specifications, such as the Serviceable interface, which is a typical Type 1 approach.
This design concept requires Spring to adopt a dynamic and flexible way to design the framework. Reflection is widely used in Spring's working principles. First, Spring needs to solve the problem of how to manage beans. Because IOC requires that beans cannot be called directly, they should adopt a passive method for collaboration. Therefore, bean management is the core part of Spring's working principles.
Reflection and introspection can sometimes bring unexpected flexibility at the code level. However, its use is also a philosophical problem sometimes, whether in the ORM design or the AOP design, there are similar problems-whether reflection is used or code generation.
In Spring, the core of this issue is in the org. springframework. beans package. BeanWrapper is the most important part. BeanWrapper, as its name implies, is the bean package. Therefore, its main task is to set attributes (including embedded attributes) and call methods for any bean. In
BeanWrapper's default implementation class BeanWrapperImpl, although the Code is long, the work done is very concentrated.
BeanWrapper
Let's take a look at how BeanWrapper works. Suppose we have two beans:
Java code
- Public class Company {
- Private String name;
- Private Employee managingDirector;
- Public String getName (){
- Return this. name;
- }
- Public void setName (String name ){
- This. name = name;
- }
- Public Employee getManagingDirector (){
- Return this. managingDirector;
- }
- Public void setManagingDirector (Employee managingDirector ){
- This. managingDirector = managingDirector;
- }
- }
- Public class Employee {
- Private float salary;
- Public float getSalary (){
- Return salary;
- }
- Public void setSalary (float salary ){
- This. salary = salary;
- }
- }
public class Company {private String name;private Employee managingDirector;public String getName() {return this.name;}public void setName(String name) {this.name = name;}public Employee getManagingDirector() {return this.managingDirector;}public void setManagingDirector(Employee managingDirector) {this.managingDirector = managingDirector;} } public class Employee {private float salary;public float getSalary() {return salary;}public void setSalary(float salary) {this.salary = salary;} }
Then we use BeanWrapper to call the two beans:
Java code
- Company c = new Company ();
- BeanWrapper bwComp = BeanWrapperImpl (c );
- // Setting the company name...
- BwComp. setPropertyValue ("name", "Some Company Inc .");
- //... Can also be done like this:
- PropertyValue v = new PropertyValue ("name", "Some Company Inc .");
- BwComp. setPropertyValue (v );
- // OK, lets create the director and tie it to the company:
- Employee jim = new Employee ();
- BeanWrapper bwJim = BeanWrapperImpl (jim );
- BwJim. setPropertyValue ("name", "Jim Stravinsky ");
- BwComp. setPropertyValue ("managingDirector", jim );
- // Retrieving the salary of the managingctor ctor through the company
- Float salary = (Float) bwComp. getPropertyValue ("managingDirector. salary ");
Company c = new Company(); BeanWrapper bwComp = BeanWrapperImpl(c); // setting the company name... bwComp.setPropertyValue("name", "Some Company Inc."); // ... can also be done like this: PropertyValue v = new PropertyValue("name", "Some Company Inc."); bwComp.setPropertyValue(v); // ok, lets create the director and tie it to the company: Employee jim = new Employee(); BeanWrapper bwJim = BeanWrapperImpl(jim); bwJim.setPropertyValue("name", "Jim Stravinsky"); bwComp.setPropertyValue("managingDirector", jim); // retrieving the salary of the managingDirector through the company Float salary = (Float)bwComp.getPropertyValue("managingDirector.salary");
It seems a lot of trouble, but Spring can manage bean attributes in a unified way.
Bean manufacturing plant
With the packaging of a single Bean, you also need to manage multiple beans. In spring, beans are incorporated into a core library for management. There are two methods for bean production: one is to generate multiple instances for one bean, and the other is to generate only one instance for one bean. If we are familiar with the design pattern, we will think that the former can adopt Prototype, and the latter can adopt Singleton.
Note that the use of reflection technology makes it easier for us to create objects as in the original factory method mode. Reflection allows you to flexibly create an object based on the class name. Therefore, spring only uses the Prototype and Singleton modes.
Spring works like this, but we hope that you can maintain a unified interface without worrying about whether the current bean is an independent bean produced by Prototype or a shared bean generated by Singleton. Therefore, BeanFactory In the org. springframework. beans. factory package defines a uniform getBean method.
JDBC Encapsulation
JDBC elegantly encapsulates the underlying database, but JDBC remains unchanged. You need to write a lot of code to complete the CRUD operation. In addition, JDBC throws a SQLException no matter what problems it encounters. This method is called incomplete information in exception usage. The problem may be complicated. It may be a database connection issue, or a concurrency control issue, but it may be an SQL statement error. There is no reason to deal with all the problems with a simple SQLException. This approach is somewhat irresponsible. To address these two problems, Spring Framework provides two solutions: first, a Framework is provided, all the common operations in JDBC applications, such as connection retrieval, exception handling, and release, are centralized. You only need to provide specific implementation. The specific implementation details use the template method. For example, in the org. springframework. jdbc. object package, the MappingSqlQuery class maps SQL queries to specific business objects. In JavaDoc, it writes: Reusable query in which concrete subclasses must implement the abstract mapRow (ResultSet, int) method to convert each row of the JDBC ResultSet into an object. you must implement the mapRow method, which is an application of the typical template method. Let's take a specific example:
Java code
- Class UserQuery extends MappingSqlQuery {
- Public UserQuery (DataSource datasource ){
- Super (datasource, "SELECT * FROM PUB_USER_ADDRESS WHERE USER_ID =? ");
- DeclareParameter (new SqlParameter (Types. NUMERIC ));
- Compile ();
- }
- // Map a result set row to a Java object
- Protected Object mapRow (ResultSet rs, int rownum) throws SQLException {
- User user = new User ();
- User. setId (rs. getLong ("USER_ID "));
- User. setForename (rs. getString ("FORENAME "));
- Return user;
- }
- Public User findUser (long id ){
- // Use superclass convenience method to provide strong typing
- Return (User) findObject (id );
- }
- }
class UserQuery extends MappingSqlQuery {public UserQuery(DataSource datasource) {super(datasource, "SELECT * FROM PUB_USER_ADDRESS WHERE USER_ID = ?");declareParameter(new SqlParameter(Types.NUMERIC));compile();}// Map a result set row to a Java objectprotected Object mapRow(ResultSet rs, int rownum) throws SQLException {User user = new User();user.setId(rs.getLong("USER_ID"));user.setForename(rs.getString("FORENAME"));return user;}public User findUser(long id) {// Use superclass convenience method to provide strong typingreturn (User) findObject(id);}}
The second is the second problem. The most troublesome issue is to block the JDBC exception, determine the exception type, and throw an exception again. Errors can be obtained through connections, so the trouble is how to intercept exceptions. The Spring Framework uses callback, and the class for processing callback is called template in Spring Framework.
Java code
- JdbcTemplate template = new JdbcTemplate (dataSource );
- Final List names = new topology List ();
- Template. query ("select user. name from user", new RowCallbackHandler (){
- Public void processRow (ResultSet rs) throws SQLException {
- Names. add (rs. getString (1 ));
- }
- });
JdbcTemplate template = new JdbcTemplate(dataSource); final List names = new LinkedList(); template.query("SELECT USER.NAME FROM USER",new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { names.add(rs.getString(1)); } });
The callback function is an anonymous class, And the template method is also used. Exception Handling is completed in the parent class.
Loose coupling
A large number of MVC-based Web containers have emerged in the open source code field, but these containers are limited to the Web scope and do not involve Web-layer backend connections. Spring is a holistic framework, defines a connection method between the Web layer and the backend service layer. This concept still applies to MVC, but the coupling is loose and does not depend on the specific integration layer.
Java code
- Public class GoogleSearchController implements Controller {
- Private IGoogleSearchPort google;
- Private String googleKey;
- Public void setGoogle (IGoogleSearchPort google ){
- This. google = google;
- }
- Public void setGoogleKey (String googleKey ){
- This. googleKey = googleKey;
- }
- Public ModelAndView handleRequest (
- HttpServletRequest request, HttpServletResponse response)
- Throws ServletException, IOException {
- String query = request. getParameter ("query ");
- GoogleSearchResult result =
- // Google property definitions omitted...
- // Use google business object
- Google. doGoogleSearch (this. googleKey, query, start, maxResults, filter, restrict, safeSearch, lr, ie, oe );
- Return new ModelAndView ("googleResults", "result", result );
- }
- }