First of all, let’s briefly introduce Spring.
Spring is an open source lightweight Java development framework with two cores: Inversion of Control (IoC) and Aspect Oriented (AOP). The Java Spring framework flexibly manages transactions in a declarative manner, improving development efficiency and quality.
(Recommended tutorial: java introductory tutorial)
The Spring framework is not limited to server-side development. Any Java application can benefit from Spring in terms of simplicity, testability, and loose coupling. The Spring framework is also a super glue platform. In addition to providing its own functions, it also provides the ability to glue other technologies and frameworks.
Next let’s introduce the specific content in detail.
Inversion of Control (IOC)
About the past, the code of the business logic layer was likely to be written like this:
public class PersonServiceBean { private PersonDao personDao = new PersonDaoBean(); public void save(Person person){ personDao.save(person); } }
It can be seen from the above that PersonDaoBean is created inside the application and maintained. The so-called inversion of control means that the application itself is not responsible for the creation and maintenance of dependent objects. The creation and maintenance of dependent objects is the responsibility of the external container. In this way, control is transferred from the application to the external container. The transfer of control is called reversal.
Dependency Injection
When we hand over the dependency object to the external container for creation, then the PersonServiceBean class can be changed as follows:
public class PersonServiceBean { private PersonDao personDao ; // 通过构造器参数,让容器把创建好的依赖对象注入进PersonServiceBean,当然也可以使用setter方法进行注入。 public PersonServiceBean(PersonDao personDao){ this.personDao=personDao; } public void save(Person person){ personDao.save(person); } }
The so-called dependency injection refers to : During runtime, the external container dynamically injects dependent objects into the component.
Why use Spring?
At least in my opinion, introducing Spring into the project can immediately bring the following benefits:
Reduce the coupling between components and achieve decoupling between the various layers of the software.
You can use many services provided by the container, such as transaction management services, message services, etc. When we use containers to manage transactions, developers no longer need to manually control transactions, nor do they need to deal with complex transaction propagation.
The container provides singleton mode support, and developers no longer need to write implementation code themselves.
Containers provide AOP technology, which can easily be used to implement functions such as permission interception and runtime monitoring.
Containers provide many auxiliary classes. Using these classes can speed up application development, such as: JdbcTemplate, HibernateTemplate.
Spring provides integrated support for mainstream application frameworks, such as integrating Hibernate, JPA, Struts, etc., which makes application development easier.
Benefits of using Spring
We have listed the benefits of using the Spring framework in detail above, and we will only elaborate on the second point. When using the Spring framework, we can use numerous services provided by the container.
Imagine if you don’t use the Spring framework, then using the Hibernate framework for transaction operations should be:
Hibernate transaction operations:
public void save(){ Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Info info = new Info("Spring框架"); info.setContent("阿昀手把手教你学习Spring框架"); session.save(info); session.getTransaction().commit(); }
Neither the Spring framework nor the Hibernate framework is used, and the most primitive JDBC technology is directly used for transaction operations. The code should be:
JDBC transaction operation:
Connection conn = null; try { ...... conn.setAutoCommit(false); Statement stmt = conn.createStatement(); stmt.executeUpdate("update person where name='叶天'"); conn.commit(); ...... } catch (Exception e) { conn.rollback(); } finally { conn.close(); }
And if Using the Spring framework, we no longer need to manually control transactions. In addition, if we use the Spring framework, we do not need to deal with complex transaction propagation behavior. Let us illustrate this with an example.
(Video tutorial recommendation: java course)
For example, there is code:
public void payment(){ Bean1.update(); // 更新金额 Bean2.save(); // 记录操作日志 }
public class Bean1 { public void update(){ // 注意:下面省略了一些代码 Connection conn = null; conn.setAutoCommit(false); Statement.executeUpdate("update account set amount=? where id=?"); } }
public class Bean2 { public void save(){ // 注意:下面省略了一些代码 Connection conn = null; conn.setAutoCommit(false); Statement.executeUpdate("insert into Log (content) values (?)"); } }
If we do not use the Spring framework, for the following two Business needs, how should we do it?
The first possible business requirement: requires Bean1.update() and Bean2.save() to be executed in the same transaction.
The second possible business requirement: It is required to record the operation log regardless of whether the transaction of Bean1.update() is successful or not.
If you do not use the Spring framework, for the first possible business requirement, our solution is expressed in code:
public void payment(){ Connection conn = null; conn.setAutoCommit(false); Bean1.update(conn); // 更新金额 Bean2.save(conn); // 记录操作日志 // ...提交或回滚事务 }
public class Bean1 { public void update(Connection conn){ // 注意:下面省略了一些代码 Statement.executeUpdate("update account set amount=? where id=?"); } }
public class Bean2 { public void save(Connection conn){ // 注意:下面省略了一些代码 Statement.executeUpdate("insert into Log (content) values (?)"); } }
For the second possible business requirement, we do not It can be completed by modifying the code, because Bean1.update() opens a transaction, and Bean2.save() also opens a transaction. The rollback of the transaction started by Bean1.update() will not affect Bean2.save() Opened transaction.
If we use the Spring framework, we can easily achieve these two business requirements through declarative transaction attribute configuration.
Requires Bean1.update() and Bean2.save() to be executed in the same transaction. We only need to change the code to:
@Transactional(propagation=Propagation.Required) public void payment(){ Bean1.update(); // 更新金额 Bean2.save(); // 记录日志 }
public class Bean1 { @Transactional(propagation=Propagation.Required) public void update(){ executeUpdate("update account set amount=? where id=?"); } }
public class Bean2 { @Transactional(propagation=Propagation.Required) public void save(){ executeUpdate("insert into Log (content) values (?)"); } }
Requires that the log needs to be recorded regardless of whether the Bean1.update() transaction is successful or not. We only need to change the code to:
@Transactional(propagation=Propagation.Required) public void payment(){ Bean1.update(); // 更新金额 Bean2.save(); // 记录日志 }
public class Bean1 { @Transactional(propagation=Propagation.Required) public void update(){ executeUpdate("update account set amount=? where id=?"); } }
public class Bean2 { @Transactional(propagation=Propagation.RequiresNew) public void save(){ executeUpdate("insert into Log (content) values (?)"); } }
Division of lightweight and heavyweight concepts
People often ask whether Spring is a lightweight framework or a heavyweight framework? In fact, whether an application is classified as lightweight or heavyweight mainly depends on how many services it uses. The more services used, the more work the container has to do for ordinary Java objects, which will inevitably affect the application release time or running performance.
For the Spring container, it provides many services, but these services are not opened by the application by default. The application needs a certain service and needs to specify the use of the service. , if the application uses very few services, such as only using Spring core services, then we can consider the application to be lightweight. If the application uses most of the services provided by Spring, then the application is heavyweight. . The current EJB container is heavyweight because it provides applications with all the functions in the EJB specification by default.
The above is the detailed content of Do you know what Spring is?. For more information, please follow other related articles on the PHP Chinese website!