使用注解实现IOC
1、注解方式将Bean的定义信息和Bean实现类结合在一起,Spring提供的注解有
@Component:实现Bean组件的定义
@Repository :用于标注DAO类
@Service :用于标注业务类
@Controller :用于标注控制器类
@Repository("userDao") public class UserDaoImpl implements UserDao { … }
等效于与在XML配置文件中编写
<bean id="userDao" class="dao.impl.UserDaoImpl" />
2、使用@Autowired注解实现Bean的自动装配,默认按类型匹配,可以使用@Qualifier指定Bean的名称
对类的成员变量进行标注
@Service("userService") public class UserServiceImpl implements UserService { @Autowired @Qualifier("userDao") private UserDao dao; …… }
也可以对方法的入参进行标注
@Service("userService") public class UserServiceImpl implements UserService { private UserDao dao; @Autowired public void setDao((@Qualifier("userDao") UserDao dao) { this.dao = dao; } …… }
3、使用注解信息启动Spring容器
<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" xsi:schemaLocation="...... http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <!-- 扫描包中注解标注的类 --> <context:component-scan base-package="service,dao" /> </beans>
4、使用Java标准注解完成装配
使用@Resource注解实现组件装配,默认按名称匹配
为dao属性注入名为userDao的Bean
@Service("userService") public class UserServiceImpl implements UserService { @Resource(name = "userDao") private UserDao dao; …… }
查找名为dao的Bean,并注入给dao属性
@Service("userService") public class UserServiceImpl implements UserService { @Resource private UserDao dao; …… }
代码实例
下面我用一个小项目完整的展示Spring使用注解实现IOC
1、User实体类
package userTest.entity; /** * @author: * @date:2019/11/4 * @aim:User实体类 */ public class User { private String name; private String pwd; public User(){} public User(String name, String pwd) { this.name = name; this.pwd = pwd; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } }
2、Dao层
package userTest.dao; import org.springframework.stereotype.Component; import userTest.entity.User; /** * @author: * @date:2019/11/4 * @aim: */ @Component("userDao") public class UserDaoImpl implements UserDao { @Override public boolean addUser(User user) { System.out.println("插入一条用户信息"); return true; } }
3、Service层
package userTest.service; import org.springframework.stereotype.Service; import userTest.dao.UserDao; import userTest.entity.User; import javax.annotation.Resource; /** * @author: * @date:2019/11/4 * @aim: */ @Service("userService") public class UserServiceImpl implements UserService { //@Autowired //@Qualifier("userDao") //两种注入方式 @Resource(name = "userDao") private UserDao dao; public UserDao getDao() { return dao; } public void setDao(UserDao dao) { this.dao = dao; } @Override public boolean add(User user) { boolean flag=dao.addUser(user); return flag; } }
4、增强类
package userTest.aop; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import userTest.service.UserService; import java.util.Arrays; /** * @author: * @date:2019/11/4 * @aim:通知类,并在通知类上添加注解,描述那些切入点应该执行哪种增强处理 */ @Controller("userAop") @Aspect public class UserServiceLogAop { Logger log= Logger.getLogger(userTest.aop.UserServiceLogAop.class); @Autowired @Qualifier("userService") private UserService service; public UserService getService() { return service; } public void setService(UserService service) { this.service = service; } @Pointcut("execution(public boolean add(userTest.entity.User))") public void pointcut(){} @Before("pointcut()") public void beforeAdd(JoinPoint jp){ log.info("调用"+jp.getTarget()+"的"+jp.getSignature()+"之前,参数为:"+ Arrays.toString(jp.getArgs())); } @AfterReturning(pointcut = "pointcut()",returning = "result") public void afterAdd(JoinPoint jp, Object result){ log.info("调用"+jp.getTarget()+"的"+jp.getSignature()+"之后,返回值为:"+result); } @After("pointcut()") public void finalTest(JoinPoint jp){ log.info(jp.getTarget()+"的"+jp.getSignature()+"方法执行结束"); } }
5、配置文件
<?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:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <!-- 扫描包中注解标注的类 --> <context:component-scan base-package="userTest" /> <!--启用对于@AspectJ注解的支持--> <aop:aspectj-autoproxy /> <!--使用p命名空间注入直接量--> <bean id="user" class="userTest.entity.User" p:name="Uzi" p:pwd="123456"/> <!--使用构造注入--> <bean id="user1" class="userTest.entity.User"> <constructor-arg index="0"> <value>TheShy</value> </constructor-arg> <constructor-arg name="pwd" > <value>123456</value> </constructor-arg> </bean> </beans>
6、测试类
package userTest.service; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import userTest.entity.User; public class UserServiceImplTest { @Test public void add() { ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext3.xml"); UserService userService=(UserService)context.getBean("userService"); User user= (User) context.getBean("user"); User user1= (User) context.getBean("user1"); userService.add(user); userService.add(user1); } }
7、结果
[INFO ] 2019-11-05 12:28:44,771 method:userTest.aop.UserServiceLogAop.beforeAdd(UserServiceLogAop.java:42) 调用userTest.service.UserServiceImpl@3c9754d8的boolean userTest.service.UserService.add(User)之前,参数为:[User{name='Uzi', pwd='123456'}] 插入一条用户信息 [INFO ] 2019-11-05 12:28:44,772 method:userTest.aop.UserServiceLogAop.finalTest(UserServiceLogAop.java:52) userTest.service.UserServiceImpl@3c9754d8的boolean userTest.service.UserService.add(User)方法执行结束 [INFO ] 2019-11-05 12:28:44,773 method:userTest.aop.UserServiceLogAop.afterAdd(UserServiceLogAop.java:47) 调用userTest.service.UserServiceImpl@3c9754d8的boolean userTest.service.UserService.add(User)之后,返回值为:true [INFO ] 2019-11-05 12:28:44,773 method:userTest.aop.UserServiceLogAop.beforeAdd(UserServiceLogAop.java:42) 调用userTest.service.UserServiceImpl@3c9754d8的boolean userTest.service.UserService.add(User)之前,参数为:[User{name='TheShy', pwd='123456'}] 插入一条用户信息 [INFO ] 2019-11-05 12:28:44,773 method:userTest.aop.UserServiceLogAop.finalTest(UserServiceLogAop.java:52) userTest.service.UserServiceImpl@3c9754d8的boolean userTest.service.UserService.add(User)方法执行结束 [INFO ] 2019-11-05 12:28:44,773 method:userTest.aop.UserServiceLogAop.afterAdd(UserServiceLogAop.java:47) 调用userTest.service.UserServiceImpl@3c9754d8的boolean userTest.service.UserService.add(User)之后,返回值为:true