目录
一、注解
由最开始的手动new对象异常繁琐,后来出现了Spring的IoC,用bean来加载对象,不过大量的bean同样也会出现大量雷同的代码,这时候注解就派上用场了。首先要扫描包<context:component-scan base-package="com.mj/> ",然后在加上@Component注解才行。
- @Component相当于<bean>标签
- 通过value属性设置bean的id,默认会将类名的首字母小写形式作为bean的id
- @Controller用于标识控制层,@Service用于标识业务层,@Repository用于标识Dao层
- @Scope:设置singleton、prototype
- @Lazy:scope为singleton时延迟加载
- 在配置文件中可以通过<context:component-scan>设置需要扫描的包,可以扫描到所有的@Component
- @ComponentScan:相当于<context:component-scan>标签
2、@Autowired注解:
- @Autowired按照类型注入bean实例,可以写在成员变量(不会调用setter)、setter上
- 可以配合使用@Qualifier:设置需要注入的bean的id
- required设置为false:找不到对应的bean时不会抛出异常
3、@Value:
- 用于注入String、基本类型、BigDecimal等类型
- 可以配合配置文件(比如properties)使用${}读取配置文件的内容
4、@PropertySources、@PropertySource
- 相当于<context:property-placeholder>
5、@Configuration
- @configuration 使用此注解的类,可以取代applicationContext.xml
- 它也是一个@Component,所以可以通过component-scan扫描
- 可以在@Configuration类中,使用@Bean修饰方法,进行bean对象的创建
- 默认情况下,方法名就是bean的id,也可以通过name、value属性设置bean的id
6、@Bean
二、注解实现AOP
- 创建aop类DefaultAspect:
package com.mj.aop; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component public class DefaultAspect { // 可以提取出来 @Pointcut("within(com.mj.service.impl.UserServiceImpl)") public void pc(){}; // 可以写一个公共的方法 @Around("pc()") public Object log(ProceedingJoinPoint point) throws Throwable { System.out.println("log1------------"); // 调用目标方法 Object ret = point.proceed(); System.out.println("log2------------"); return ret; } @Around("within(com.mj.service.impl.UserServiceImpl)") public Object watch(ProceedingJoinPoint point) throws Throwable { System.out.println("watch1------------"); // 调用目标方法 Object ret = point.proceed(); System.out.println("watch2------------"); return ret; } }
- service实现类
package com.mj.service.impl; import com.mj.service.UserService; import org.springframework.stereotype.Service; @Service("userService") public class UserServiceImpl implements UserService { public void list() { System.out.println("UserServiceImpl ---- list"); } }
- 配置文件
<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <context:component-scan base-package="com.mj"/> <aop:aspectj-autoproxy/> </beans>
- 测试类
@Test public void test() { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = ctx.getBean("userService", UserService.class); userService.list(); }
工程打印如下图:
三、注解事务管理
- @Transactional 可以在需要进行事物管理的类(比如Service)上使用这个注解,代表所有的方法都会自动管理事务
- 可以在需要进行事物管理的方法上使用这个注解(可以覆盖类中的@Transactional的配置)
- 可以设置isolation、propagation、timeout、rollbackFor、readOnly等属性
- 使用<tx:annotation-driven>取代之前的<tx:advice>、<aop:config>
1、首先配置文件里的配置:
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--引用db.properties文件的内容-->
<context:property-placeholder location="db.properties"/>
<!-- 配置数据源(Druid) -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!-- <bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">-->
<!-- <property name="driver" value="${driverClass}"/>-->
<property name="driverClassName" value="${driverClass}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</bean>
<!-- 创建SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--数据源-->
<property name="dataSource" ref="dataSource"/>
<!--设置别名,这个包里面的类会自动设置别名-->
<property name="typeAliasesPackage" value="com.mj.domain"/>
<!--mybatis文件映射文件的位置-->
<property name="mapperLocations">
<list>
<value>mappers/*.xml</value>
</list>
</property>
</bean>
<!--扫描Dao-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--SqlSessionFactoryBean的id-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--dao的包名-->
<property name="basePackage" value="com.mj.dao"/>
</bean>
<!--纯注解aop-->
<context:component-scan base-package="com.mj"/>
<aop:aspectj-autoproxy/>
<!--事务管理器-->
<bean id="txMgr" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--注解事务驱动-->
<tx:annotation-driven transaction-manager="txMgr"/>
</beans>
2、实现类代码
package com.mj.service.impl;
import com.mj.dao.SkillDao;
import com.mj.domain.Skill;
import com.mj.service.SkillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service("skillService")
@Transactional
public class SkillServiceImpl implements SkillService {
@Autowired
private SkillDao dao;
public void setDao(SkillDao dao) {
this.dao = dao;
}
public List<Skill> list() {
return dao.list();
}
public boolean save(Skill skill) {
return dao.save(skill);
}
public boolean update(Skill skill) {
return dao.update(skill);
}
public void test() {
Skill skill = new Skill("777",777);
skill.setId(2);
dao.update(skill);
System.out.println(10/0);
dao.save(new Skill("888",888));
}
}
3、测试结果如下图:
四、总结(bean的创建方式)
在spring中,bean有3种常见的创建方式
- @Component:常用于源码可修改、创建过程比较简单(直接调用构造方法即可)的类型
- @Bean:常用于源码不可修改的类型(比如第三方库的类型)或者创建过程比较复杂的类型
- <bean>:适用于所有类型
当上述三种方式bean的id相同时(不相同时都会创建),优先级如下:
- <bean>大于@Bean大于@Component
- 因为<bean>可以用于覆盖以前的@Bean、@Component的内容,所以减少@Bean、@Component代码的变动