IOC 操作 Bean 管理(基于注解方式)
1、什么是注解
(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值…)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解目的:简化 xml 配置
2、Spring 针对 Bean 管理中创建对象提供注解
下面四个注解功能是一样的,都可以用来创建 bean 实例
(1)@Component
(2)@Service
(3)@Controller
(4)@Repository
3、基于注解方式实现对象创建
第一步 引入依赖 (引入spring-aop jar包)
第二步 开启组件扫描
1 2 3 4 5
|
<context:component-scan base-package="com.atguigu"></context:component-scan>
|
第三步 创建类,在类上面添加创建对象注解
1 2 3 4 5 6 7 8 9
|
@Component(value = "userService") public class UserService { public void add() { System.out.println("service add......."); } }
|
4、开启组件扫描细节配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
<context:component-scan base-package="com.atguigu" use-defaultfilters="false"> <context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/> </context:component-scan>
<context:component-scan base-package="com.atguigu"> <context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/> </context:component-scan>
|
5、基于注解方式实现属性注入
(1)@Autowired:根据属性类型进行自动装配
第一步 把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解
第二步 在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Service public class UserService { @Autowired private UserDao userDao; public void add() { System.out.println("service add......."); userDao.add(); } }
@Repository
public class UserDaoImpl implements UserDao { @Override public void add() { System.out.println("dao add....."); } }
|
(2)@Qualifier:根据名称进行注入,这个@Qualifier 注解的使用,和上面@Autowired 一起使用
1 2 3 4 5 6 7
|
@Autowired
@Qualifier(value = "userDaoImpl1") private UserDao userDao;
|
(3)@Resource:可以根据类型注入,也可以根据名称注入(它属于javax包下的注解,不推荐使用!)
1 2 3
| @Resource(name = "userDaoImpl1") private UserDao userDao;
|
(4)@Value:注入普通类型属性
1 2
| @Value(value = "abc") private String name
|
6、完全注解开发
(1)创建配置类,替代 xml 配置文件
1 2 3 4 5
| @Configuration @ComponentScan(basePackages = {"com.atguigu"}) public class SpringConfig { }
|
(2)编写测试类
1 2 3 4 5 6 7 8
| @Test public void testService2() { ApplicationContext context= new AnnotationConfigApplicationContext(SpringConfig.class); UserService userService = context.getBean("userService",UserService.class); System.out.println(userService); userService.add(); }
|
Spring-AOP
1、AOP 基本概念
(1)面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得 业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
(2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能
(3)使用登录例子说明 AOP
2、AOP(底层原理)
a)AOP 底层使用动态代理 ,动态代理有两种情况:
第一种 有接口情况,使用 JDK 动态代理 ;创建接口实现类代理对象,增强类的方法
第二种 没有接口情况,使用 CGLIB 动态代理;创建子类的代理对象,增强类的方法
3、AOP(JDK 动态代理)
1)使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象
调用 newProxyInstance 方法,方法有三个参数:
1 2 3
| public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
|
第一参数,类加载器
第二参数,增强方法所在的类,这个类实现的接口,支持多个接口
第三参数,实现这个接口 InvocationHandler,创建代理对象,写增强的部分
2)编写 JDK 动态代理代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| public interface UserDao { public int add(int a,int b); public String update(String id); }
public class UserDaoImpl implements UserDao { @Override public int add(int a, int b) { return a+b; } @Override public String update(String id) { return id; } }
public class JDKProxy { public static void main(String[] args) { Class[] interfaces = {UserDao.class}; UserDaoImpl userDao = new UserDaoImpl();
UserDao dao =(UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao)); int result = dao.add(1, 2); System.out.println("result:"+result); } }
class UserDaoProxy implements InvocationHandler { private Object obj; public UserDaoProxy(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("方法之前执行...."+method.getName()+" :传递的参数..."+ Arrays.toString(args)); Object res = method.invoke(obj, args); System.out.println("方法之后执行...."+obj); return res; } }
|
4、AOP(术语)
a)连接点:类里面哪些方法可以被增强,这些方法称为连接点
b)切入点:实际被真正增强的方法称为切入点
c)通知(增强):实际增强的逻辑部分称为通知,且分为以下五种类型:
1)前置通知:在增强方法前执行
2)后置通知 :在增强方法后执行
3)环绕通知 :在增强方法的前后都执行
4)异常通知 :在增强方法抛出异常后执行
5)最终通知:在所有方法执行后执行
d)切面:把通知应用到切入点过程
5、AOP操作
a)Spring 框架一般都是基于 AspectJ 实现 AOP 操作,AspectJ 不是 Spring 组成部分,独立 AOP 框架,一般把 AspectJ 和 Spirng 框架一起使 用,进行 AOP 操作
b)基于 AspectJ 实现 AOP 操作:1)基于 xml 配置文件实现 (2)基于注解方式实现(使用)
c)引入相关jar包
d)切入点表达式,如下:
1 2 3 4 5 6 7 8 9
| (1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强 (2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) ) (3)例子如下: 例 1:对 com.atguigu.dao.BookDao 类里面的 add 进行增强 execution(* com.atguigu.dao.BookDao.add(..)) 例 2:对 com.atguigu.dao.BookDao 类里面的所有的方法进行增强 execution(* com.atguigu.dao.BookDao.* (..)) 例 3:对 com.atguigu.dao 包里面所有类,类里面所有方法进行增强 execution(* com.atguigu.dao.*.* (..))
|
6、AOP 操作(AspectJ 注解)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class User { public void add() { System.out.println("add......."); } }
public class UserProxy { public void before() { System.out.println("before......"); } } <!--3、进行通知的配置--> <?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 开启注解扫描 --> <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan>
<!-- 开启Aspect生成代理对象--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
@Component @Aspect public class UserProxy {}
@Component public class User {}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| @Component @Aspect public class UserProxy { @Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void pointdemo() {
}
@Before(value = "pointdemo()") public void before() { System.out.println("before........."); }
@AfterReturning(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void afterReturning() { System.out.println("afterReturning........."); }
@After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void after() { System.out.println("after........."); }
@AfterThrowing(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void afterThrowing() { System.out.println("afterThrowing........."); }
@Around(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("环绕之前.........");
proceedingJoinPoint.proceed();
System.out.println("环绕之后........."); } }
|
7、有多个增强类对同一个方法进行增强,设置增强类优先级
1 2 3 4 5
| @Component @Aspect @Order(1) public class PersonProxy{ }
|
8、AOP 操作(AspectJ 配置文件)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
<bean id="book" class="com.atguigu.spring5.aopxml.Book"></bean> <bean id="bookProxy" class="com.atguigu.spring5.aopxml.BookProxy"></bean>
<aop:config> <aop:pointcut id="p" expression="execution(* com.atguigu.spring5.aopxml.Book.buy(..))"/> <aop:aspect ref="bookProxy"> <aop:before method="before" pointcut-ref="p"/> </aop:aspect> </aop:config>
|
JdbcTemplate
1、概念及使用
a)Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作
b)引入相关 jar 包
c)在 spring 配置文件配置数据库连接池
1 2 3 4 5 6 7
| <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="url" value="jdbc:mysql:///test" /> <property name="username" value="root" /> <property name="password" value="root" /> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> </bean>
|
d)配置 JdbcTemplate 对象,注入 DataSource
1 2 3 4 5
| <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
|
e)创建 service 类,创建 dao 类,在 dao 注入 jdbcTemplate 对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <context:component-scan base-package="com.atguigu"></context:component-scan> @Service public class BookService { //注入 dao @Autowired private BookDao bookDao; }
@Repository public class BookDaoImpl implements BookDao { //注入 JdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; }
|
2、操作数据库(添加)
a)对应数据库创建实体类
b)创建service和dao
(1)在 dao 进行数据库添加操作
(2)调用 JdbcTemplate 对象里面 update 方法实现添加操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Repository public class BookDaoImpl implements BookDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public void add(Book book) { String sql = "insert into t_book values(?,?,?)"; Object[] args = {book.getUserId(), book.getUsername(),book.getUstatus()}; int update = jdbcTemplate.update(sql,args); System.out.println(update); } }
|
3、 操作数据库(修改和删除)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Override public void updateBook(Book book) { String sql = "update t_book set username=?,ustatus=? where user_id=?"; Object[] args = {book.getUsername(), book.getUstatus(),book.getUserId()}; int update = jdbcTemplate.update(sql, args); System.out.println(update); }
@Override public void delete(String id) { String sql = "delete from t_book where user_id=?"; int update = jdbcTemplate.update(sql, id); System.out.println(update); }
|
4、操作数据库(查询返回某个值)
1 2 3 4 5 6 7 8
| @Override public int selectCount() { String sql = "select count(*) from t_book";
Integer count = jdbcTemplate.queryForObject(sql, Integer.class); return count; }
|
5、 操作数据库(查询返回对象)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Override public Book findBookInfo(String id) { String sql = "select * from t_book where user_id=?";
Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id); return book; }
|
6、 操作数据库(查询返回集合)
1 2 3 4 5 6 7 8 9
|
@Override public List<Book> findAllBook() { String sql = "select * from t_book"; List<Book> bookList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class)); return bookList; }
|
7、 操作数据库(批量操作)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Override public void batchAddBook(List<Object[]> batchArgs) { String sql = "insert into t_book values(?,?,?)";
int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs); System.out.println(Arrays.toString(ints)); }
List<Object[]> batchArgs = new ArrayList<>(); Object[] o1 = {"3","java","a"}; Object[] o2 = {"4","c++","b"}; Object[] o3 = {"5","MySQL","c"}; batchArgs.add(o1); batchArgs.add(o2); batchArgs.add(o3);
bookService.batchAdd(batchArgs);
|
8、实现批量修改操作
1 2 3 4 5 6 7
| @Override public void batchUpdateBook(List<Object[]> batchArgs) { String sql = "update t_book set username=?,ustatus=? where user_id=?"; int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs); System.out.println(Arrays.toString(ints)); }
|