点一下关注吧!!!非常感谢!!持续更新!!!
大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html
目前已经更新到了:
- MyBatis(已更完)
- Spring(正在更新…)
XML与注解结合的方式
需要注意:
- 实际企业开发中,纯 XML 模式已经很少使用了
- 引入注解功能,不需要引入额外的 Jar
- XML+注解结合模式,XML 文件依然存在,所以,Spring IoC 容器仍然是从加载 XML 开始。
- 哪些 Bean 定义需要写到 XML 中,哪些 Bean 的定义使用注解
简单来说,第三方的 Jar 中的 Bean 定义在 XML 中,自己开发的 Bean 使用注解的方式。
XML中标签与注解的对应
DI 依赖注入的注解实现方式
推荐使用 Autowired,该注解是 Spring 提供的注解,采取的策略为【按照类型注入】:
public class WzkTransferServiceImpl {
@Autowired
private WzkAccountDao wzkAccountDao;
}
如上代码所示,这样装配回去 Spring 容器中找到类型为 AccountDao 的类,然后将其注入进来。这样会产生一个问题,当一个类型有多个 Bean 的值的时候,会造成无法选择具体注入哪一个的情况,这个时候我们需要配合着使用 Qualifier 注解。
Quailier 会告诉 Spring 用哪个对象来注入:
public class WzkTransferServiceImpl {
@Autowired
@Qualifier(name="jdbcWzkAccountDaoImpl")
private WzkAccountDao wzkAccountDao;
}
当然,我们也可以使用 JDK 提供的 Resource 注解,该注解默认按照【byName】自动注入:
public class WzkTransferService {
@Resource
private AccountDao accountDao;
@Resource(name="studentDao")
private StudentDao studentDao;
@Resource(type="TeacherDao")
private TeacherDao teacherDao;
@Resource(name="manDao",type="ManDao")
private ManDao manDao;
}
这里需要注意:
- 如果同时指定了 name 和 type,则从 Spring 上下文中寻找唯一匹配的 Bean进行装配。
- 如果指定了 name,则从上下文中查找名称(id)匹配的 bena 进行装配,找不到则抛出异常
- 如果指定了 type,则从上下文找到类似的匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常
- 如果既没有指定 name,又没有的指定 type,则自动按照 byName 方式进行装配
我们需要注意的是:
Resource 在 JDK11 中已经移除了,如果要使用的话,需要单独引入 Jar 包:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
applicationContext.xml
写入内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
">
</beans>
对应的截图如下所示:
对应截图如下所示:
我们之前是自己写的 beans.xml,我们现在希望借助 Spring 的情况下,一步一步改造我们之前自己手动控制 Bean 的方式。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
对应的截图如下所示:
配置改造
接下来我们将刚才的 纯 XML 的模式的代码,改造成 注解 + XML 的方式,解放出一定的 XML 来。
比如在 纯 XML 模式下,我们写的:
<!-- 配置 Bean -->
<bean id="wzkTransferService" class="wzk.service.impl.WzkTransferServiceImpl">
<constructor-arg name="wzkAccountDao" ref="wzkAccountDao"></constructor-arg>
</bean>
这个目的是让 Spring 接管我们的 Bean,而此时,我们可以将这一系列的 Bean 配置都移除出去,使用注解的方式来满足我们的 Bean 管理。
此时,我们将 Bean 的 XML 配置移除,并在需要交由 Spring 管理的 Bean 上加入注解、加入DI 的管理。
但是此时,Spring 是不知道哪些对象要处理的,所以我们需要告诉 Spring 哪些需要进行扫描:
<context:annotation-config/>
<context:component-scan base-package="wzk"/>
对应的结果如下图所示:
JdbcWzkAccountDaoImpl
这里加入注解和 ID 的管理方式,部分如下:
@Component
public class JdbcWzkAccountDaoImpl implements WzkAccountDao {
@Autowired
private WzkConnectionUtils wzkConnectionUtils;
// public void setWzkConnectionUtils(WzkConnectionUtils wzkConnectionUtils) {
// this.wzkConnectionUtils = wzkConnectionUtils;
// }
对应截图如下所示:
WzkTransferServiceImpl
@Component
public class WzkTransferServiceImpl implements WzkTransferService {
@Autowired
private WzkAccountDao wzkAccountDao;
对应的就截图如下所示:
WzkServlet(重要!!!)
这里需要注意,按理来说,我们应该在 WzkServlet 上也写 Compont 和 Autowired 来注入我们的 WzkTransferService,但是实际上呢,Component 和 Servlet 注解是冲突的。
- WebServlet 是 Servlet 的注解,交由给 Tomcat 管理。
- Component 是 Spring 的注解,交由给 Spring 管理。
此时要求我们不能在这里使用 Component注解,我们需要用 WebApplicationContext 来进行处理:
@WebServlet(name="wzkServlet", urlPatterns = "/wzkServlet")
public class WzkServlet extends HttpServlet {
private WzkTransferService wzkTransferService;
@Override
public void init() throws ServletException {
ApplicationContext context = WebApplicationContextUtils
.getWebApplicationContext(getServletContext());
this.wzkTransferService = context.getBean(WzkTransferService.class);
}
@Override
protected void doGet(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp) throws javax.servlet.ServletException, IOException {
try {
wzkTransferService.transfer("1", "2", 100);
} catch (Exception e) {
e.printStackTrace();
System.out.println("=== transfer error ====");
}
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().print("=== WzkServlet doGet ===");
}
}
对应的截图如下所示:
工具类
比如用到的一些工具,我们有依赖关系,所以也交给 Spring 进行管理,这里就不一一写了,大家用到了自己注入即可。
@Component
public class WzkConnectionUtils {
private final ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
对应的截图如下: