注解开发——Spring整合dao/service/web
发布日期:2021-07-27 04:56:20 浏览次数:6 分类:技术文章

本文共 6425 字,大约阅读时间需要 21 分钟。

一、IoC之基于注解方式

@Service 业务类专用

@Repository dao实现类专用
@Controller web层专用
@Component 通用
@Scope 用户控制bean的创建模式
部分 <bean> 可以省略 !!

1.1 基本步骤

(1)添加context依赖

org.springframework
spring-context
4.3.6.RELEASE

(2)配置applicationContext.xml文件【重要】

(3)使用注解

@Component("user")public class User {
private Integer id; private String name; ...}@Component("userservice")public class UserServiceImpl implements UserService {
@Override public void add(User user) {
System.out.println("增加用户"); } @Override public User findById(Integer id) {
System.out.println("根据id查找用户"); return new User(2,"王者"); }}//测试public class AppTest {
@Test public void testUser2() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = (User) context.getBean("user"); System.out.println("user=" + user); } @Test public void testUser3() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("userservice"); userService.add(new User(2, "鹿血")); userService.findById(2); }}

1.2 其他注解形式

在这里插入图片描述

1.2.1 类头部可用的注解

指定对象作用域

@Scope(scopeName="singleton")@Scope(scopeName="prototype")

1.2.2 注入属性value值

(1)设置成员变量:通过反射给变量赋值

其原理就是内省,详见

@Value("name值")private String name;

@Value(“name值”) 等同于 @Value(value=“name值”)

(2)加在set方法上:通过set方法赋值

@Value("tom")public void setName(String name){
this.name = name;}

1.2.3 自动装配

@Autowired 基于类型自动注入

@Resource 基于名称自动注入

更便捷的注入方式 !!

(1) @Autowired

使用 @Autowired 自动装配对象类型的属性: 下面的Person中的Car使用了自动装配

//将Car定义成接口@Componentpublic interface Car {
void log();}//Baoma实现Car@Componentpublic class Baoma implements Car {
public void log() {
System.out.println("宝马"); }}//XianDai实现Car@Componentpublic class XianDai implements Car {
public void log() {
System.out.println("现代"); }}

装配类:

@Scope(scopeName = "prototype")@Component("person")public class Person {
@Value("name值") private String name; private Integer age; @Autowired private Car car; //自动装配 可以选择Car,如果Car是接口,找Car的实现类!

注意: 以上操作会出现一个问题,如果Car是接口,且Car只有一个实现类,那么@Autowired会自动将实现类装配给Person的car变量上

但是如果Car是接口,并且有两个以上实现类,那么自动装配就会报错【expected single matching bean but found 2: BMW,xiandai】,无法选择由哪个实现类赋值.所以需要配合另一个注释@Qualifier(“bean name”), 这个属性可以将@Autowired按类型赋值改成按bean名字赋值.

(2)@Qualifier

  • 如果匹配多个类型一致的对象,将无法选择具体注入哪一个对象
  • 使用@Qualifier()注解告诉Spring容器自动装配哪个名称的对象。
@Scope(scopeName = "prototype")@Component("person")public class Person {
@Value("name值") private String name; private Integer age; @Autowired @Qualifier("baoma") //指定实现类 private Car car; //自动装配 可以选择Car,如果Car是接口,找Car的实现类!

1.2.4 @Resource

@Resource 是java的注释,但是Spring框架支持,@Resource指定注入哪个名称的对象

@Resource(“name”) == @Autowired + @Qualifier(“name”)

@Resource(name="baoma") private Car car;

1.2.5 初始化和销毁方法

初始化和销毁方法等同于配置文件添加的init-method和destroy-method功能,

例:Person类中init方法和destroy方法添加如下注解:

@PostConstruct public  void init(){
System.out.println("初始化方法"); } @PreDestroy public void destroy(){
System.out.println("销毁方法"); }

二、事务注解

@Transactional 用于为业务中切入事务

工厂配置中的 <tx:advice… 和 <aop:config… 可以省略 !!

@Transactional(isolation=Isolation.READ_COMMITTED,propagation=Propagation.REQUIRED,readOnly=false,rollbackFor=Exception.class)

在这里插入图片描述

使用事务注解需要注意的问题

/*** (1)遵从同一个接口的实现类,调用其他带有事务注解的实现类的时候,必须使用代理* (2)事务注解最好加上rollbackFor=Exception.class* (3)事务方法C内部不要有try-catch,如果有,则必须手动回滚* (4)像testD这种,属于事务嵌套,也就是事务传播,遵从传播行为* (5)不要滥用事务,因为开启事务就意味着,直到commit之前,该方法一直占用数据库连接源* 会导致数据库崩溃;事务一般用于操作数据库,保证操作一致性,可以针对数据库的增删改,进行* 方法提取,最好里面的处理很少,然后加上事务注解*/@Servicepublic class Aimpl implements A {
@Override public void testB() {
A service = (A)A opContext.currentProxy(); service.testC(); } @Override @Transactional(rollbackFor=Exception.class) public void testC() {
//事务处理 }}@Servicepublic class Timpl implements T {
@Resource private A a; @Override @Transactional(rollbackFor=Exception.class) public void testD() {
a.testC(); }}

三、@AspectJ

@Aspect // AspectJ的注解 定义切面

@Component 通用,声明当前组件
@Order(1) //执行顺序,如果有两个 Aspect,都切了相同的点,则可以区分顺序

//日志切面,增加的额外记录时间的功能@Aspect //声明,当前组件是一个切面组件@Component //声明当前组件public class Mylog {
//定义切入点,这里log就是一个代号,表示切入的地方,具体标记在哪里,在execution参数体现 @Pointcut("execution(* com.rj.service.impl.UserServiceImpl.*(..))") public void log() {
} //编织,前置额外功能,JoinPoint就是切入点 @Before("log()") public void mylog(JoinPoint joinPoint) {
String methodname = joinPoint.getSignature().getName(); System.out.println(methodname+"于"+new Date() +"被访问了"); }}

四、简化开发案例

以案例为主

4.1 applicationContext.xml文件的简化

resonable=true

4.2 service业务层简化,不需要set方法

//service默认是“userServiceImpl”,可以另起名//事务处理,与xml参数一致@Service(value = "userService")@Transactional(isolation = Isolation.REPEATABLE_READ,propagation = Propagation.REQUIRED,rollbackFor = Exception.class)//@Scope("prototype")//多例模式public class UserServiceImpl implements UserService {
//注入userDao,AutoWired是根据属性类型注入,Resource根据属性名注入 @Autowired private UserDao userDao; @Override public void change(Integer pay, Integer sav, BigDecimal money) {
User payer = new User(); User saver = new User(); payer.setId(pay); payer.setMoney(new BigDecimal(0).subtract(money)); saver.setId(sav); saver.setMoney(money); try {
//付款 userDao.update(payer); int i = 10 / 0; //收款 userDao.update(saver); System.out.println("转账成功"); } catch (Exception e) {
e.printStackTrace(); throw new RuntimeException("转账失败", e); } } @Override @Transactional(propagation = Propagation.SUPPORTS) public List
findAll() {
return userDao.findAll(); }}

转载地址:https://blog.csdn.net/qq_45337431/article/details/101428196 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Git的应用
下一篇:Spring整合dao/service/web

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年09月22日 02时53分13秒